blob: df3c4772851996706a57ee4f41346701e00159b0 [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
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200937 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000938 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000939 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000940 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000941 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200942 // If this is the last flow for the device we need to announce it the waiting
943 // chReconcilingFlowsFinished channel
944 if flowsProcessed == len(uniData.PersFlowParams)-1 {
945 lastFlowToReconcile = true
946 }
mpagenko01e726e2020-10-23 09:45:29 +0000947 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000948 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000949 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000951 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200952 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000953 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000954 }
mpagenkof1fc3862021-02-16 10:09:52 +0000955 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000957 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000958 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000959 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200960 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000961 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000962 }
963 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000964 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000965 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000966 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
967 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
968 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200969 // this can't be used as global finished reconciling flag because
970 // assumes is getting called before the state machines for the last flow is completed,
971 // while this is not guaranteed.
972 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 }
974 if !flowsFound {
975 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
976 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000977 if !dh.isSkipOnuConfigReconciling() {
978 dh.stopReconciling(ctx)
979 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 return
981 }
982 if dh.isSkipOnuConfigReconciling() {
983 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000984 }
985}
986
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000987func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
988 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000989 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000990}
991
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
993 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000994
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000996 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000997 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000998 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000999 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001000 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001001
1002 // deadline context to ensure completion of background routines waited for
1003 //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 +05301004 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001006
1007 pDevEntry.resetKvProcessingErrorIndication()
1008
1009 var wg sync.WaitGroup
1010 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1012 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001014 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001016}
1017
mpagenko15ff4a52021-03-02 10:09:20 +00001018//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1019// before this change here return like this was used:
1020// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1021//was and is called in background - error return does not make sense
1022func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1023 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1024 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001025 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001026 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001027 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301029 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001030 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001031 return
Himani Chawla4d908332020-08-31 12:30:20 +05301032 }
mpagenko01e726e2020-10-23 09:45:29 +00001033
1034 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001035 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001036
dbainbri4d3a0dc2020-12-02 00:33:42 +00001037 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001038 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001039 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001040 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001041 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001042 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001043 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001044 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001045 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001046 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001047 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001048 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001049 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1050 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1051 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1052 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001053}
1054
mpagenkoc8bba412021-01-15 15:38:44 +00001055//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001056func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1057 apDownloadManager *adapterDownloadManager) error {
1058 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001059 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001060
1061 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001062 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1063 if pDevEntry == nil {
1064 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1065 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1066 }
1067
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001068 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001069 var inactiveImageID uint16
1070 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1071 dh.lockUpgradeFsm.Lock()
1072 defer dh.lockUpgradeFsm.Unlock()
1073 if dh.pOnuUpradeFsm == nil {
1074 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1075 if err == nil {
1076 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1077 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1078 "device-id": dh.deviceID, "error": err})
1079 }
1080 } else {
1081 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001082 "device-id": dh.deviceID, "error": err})
1083 }
mpagenko15ff4a52021-03-02 10:09:20 +00001084 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1085 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1086 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1087 if pUpgradeStatemachine != nil {
1088 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1089 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1090 "device-id": dh.deviceID, "error": err})
1091 }
1092 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1093 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1094 // for now a second start of download should work again
1095 } else { //should never occur
1096 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1097 "device-id": dh.deviceID})
1098 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001099 }
mpagenko80622a52021-02-09 16:53:23 +00001100 }
mpagenko15ff4a52021-03-02 10:09:20 +00001101 } else {
1102 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1103 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001104 }
1105 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001106 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1107 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001108 }
1109 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001110}
1111
mpagenkoc26d4c02021-05-06 14:27:57 +00001112//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1113// after the OnuImage has been downloaded to the adapter, called in background
1114func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1115 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1116
1117 var err error
1118 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1119 if pDevEntry == nil {
1120 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1121 return
1122 }
1123
1124 var inactiveImageID uint16
1125 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1126 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1127 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1128 dh.lockUpgradeFsm.Lock()
1129 defer dh.lockUpgradeFsm.Unlock()
1130 if dh.pOnuUpradeFsm == nil {
1131 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1132 // but none yet defined
1133 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1134 if err == nil {
1135 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1136 apImageRequest, apDownloadManager, aImageIdentifier, dh.pOpenOnuAc.dlToOnuTimeout4M); err != nil {
1137 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1138 "device-id": dh.deviceID, "error": err})
1139 return
1140 }
1141 } else {
1142 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1143 "device-id": dh.deviceID, "error": err})
1144 }
1145 return
1146 }
1147 //OnuSw upgrade already running - restart (with possible abort of running)
1148 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1149 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1150 if pUpgradeStatemachine != nil {
1151 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1152 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1153 "device-id": dh.deviceID, "error": err})
1154 return
1155 }
1156 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1157 // for now a second start of download should work again - must still be initiated by user
1158 } else { //should never occur
1159 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1160 "device-id": dh.deviceID})
1161 }
1162 return
1163 }
1164 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1165 "device-id": dh.deviceID, "error": err})
1166}
1167
1168//onuSwActivateRequest ensures activation of the requested image with commit options
1169func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context, aVersion string, aCommitRequest bool) {
1170 var err error
1171 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1172 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1173 // 2.) activation of the inactive image
1174
1175 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1176 if pDevEntry == nil {
1177 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1178 return
1179 }
1180 dh.lockUpgradeFsm.RLock()
1181 if dh.pOnuUpradeFsm != nil {
1182 dh.lockUpgradeFsm.RUnlock()
1183 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1184 dh.deviceID, dh.deviceID)
1185 if getErr != nil || onuVolthaDevice == nil {
1186 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
1187 return
1188 }
1189 // use the OnuVendor identification from this device for the internal unique name
1190 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1191 // 1.) check a started upgrade process and rely the activation request to it
1192 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
1193 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1194 "device-id": dh.deviceID, "error": err})
1195 } else {
1196 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1197 "device-id": dh.deviceID, "image-id": imageIdentifier})
1198 }
1199 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
1200 // (even though parameter setting is not accepted)
1201 return
1202 } //else
1203 dh.lockUpgradeFsm.RUnlock()
1204
1205 // 2.) check if requested image-version equals the inactive one and start its activation
1206 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1207 var inactiveImageID uint16
1208 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1209 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1210 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
1211 return
1212 }
1213 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1214 if err == nil {
1215 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1216 inactiveImageID, aCommitRequest); err != nil {
1217 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1218 "device-id": dh.deviceID, "error": err})
1219 return
1220 }
1221 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1222 "device-id": dh.deviceID, "image-version": aVersion})
1223 return
1224 } //else
1225 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1226 "device-id": dh.deviceID, "error": err})
1227}
1228
1229//onuSwCommitRequest ensures commitment of the requested image
1230func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context, aVersion string) {
1231 var err error
1232 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1233 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1234 // 2.) commitment of the active image
1235
1236 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1237 if pDevEntry == nil {
1238 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1239 return
1240 }
1241 dh.lockUpgradeFsm.RLock()
1242 if dh.pOnuUpradeFsm != nil {
1243 dh.lockUpgradeFsm.RUnlock()
1244 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1245 dh.deviceID, dh.deviceID)
1246 if getErr != nil || onuVolthaDevice == nil {
1247 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
1248 return
1249 }
1250 // use the OnuVendor identification from this device for the internal unique name
1251 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1252 // 1.) check a started upgrade process and rely the commitment request to it
1253 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
1254 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1255 "device-id": dh.deviceID, "error": err})
1256 } else {
1257 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1258 "device-id": dh.deviceID, "image-id": imageIdentifier})
1259 }
1260 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
1261 // (even though parameter setting is not accepted)
1262 return
1263 } //else
1264 dh.lockUpgradeFsm.RUnlock()
1265
1266 // 2.) check if requested image-version equals the inactive one and start its commitment
1267 var activeImageID uint16
1268 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1269 logger.Errorw(ctx, "get active image failed", log.Fields{
1270 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
1271 return
1272 }
1273 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1274 if err == nil {
1275 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1276 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1277 "device-id": dh.deviceID, "error": err})
1278 return
1279 }
1280 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1281 "device-id": dh.deviceID, "image-version": aVersion})
1282 return
1283 } //else
1284 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1285 "device-id": dh.deviceID, "error": err})
1286}
1287
Himani Chawla6d2ae152020-09-02 13:11:20 +05301288// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001289// #####################################################################################
1290
1291// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301292// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001293
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1295 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 +00001296}
1297
1298// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001299func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001300
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001302 var err error
1303
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001304 // populate what we know. rest comes later after mib sync
1305 dh.device.Root = false
1306 dh.device.Vendor = "OpenONU"
1307 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001308 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001309 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001310
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001311 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001312
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001313 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1315 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301316 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001317 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001318 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001319 log.Fields{"device-id": dh.deviceID})
1320 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001321
Himani Chawla4d908332020-08-31 12:30:20 +05301322 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001323 dh.ponPortNumber = dh.device.ParentPortNo
1324
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001325 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1326 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1327 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001328 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301330 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001331
1332 /*
1333 self._pon = PonPort.create(self, self._pon_port_number)
1334 self._pon.add_peer(self.parent_id, self._pon_port_number)
1335 self.logger.debug('adding-pon-port-to-agent',
1336 type=self._pon.get_port().type,
1337 admin_state=self._pon.get_port().admin_state,
1338 oper_status=self._pon.get_port().oper_status,
1339 )
1340 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001341 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001342 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001343 var ponPortNo uint32 = 1
1344 if dh.ponPortNumber != 0 {
1345 ponPortNo = dh.ponPortNumber
1346 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001347
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001348 pPonPort := &voltha.Port{
1349 PortNo: ponPortNo,
1350 Label: fmt.Sprintf("pon-%d", ponPortNo),
1351 Type: voltha.Port_PON_ONU,
1352 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301353 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001354 PortNo: ponPortNo}}, // Peer port is parent's port number
1355 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001356 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1357 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001358 e.Cancel(err)
1359 return
1360 }
1361 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001363 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001364 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001365}
1366
1367// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001369
dbainbri4d3a0dc2020-12-02 00:33:42 +00001370 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001371 var err error
1372 /*
1373 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1374 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1375 return nil
1376 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001377 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1378 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001379 e.Cancel(err)
1380 return
1381 }
1382
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001383 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001384 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001385 // reconcilement will be continued after mib download is done
1386 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001387
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001388 /*
1389 ############################################################################
1390 # Setup Alarm handler
1391 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1392 device.serial_number)
1393 ############################################################################
1394 # Setup PM configuration for this device
1395 # Pass in ONU specific options
1396 kwargs = {
1397 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1398 'heartbeat': self.heartbeat,
1399 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1400 }
1401 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1402 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1403 self.logical_device_id, device.serial_number,
1404 grouped=True, freq_override=False, **kwargs)
1405 pm_config = self._pm_metrics.make_proto()
1406 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1407 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1408 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1409
1410 # Note, ONU ID and UNI intf set in add_uni_port method
1411 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1412 ani_ports=[self._pon])
1413
1414 # Code to Run OMCI Test Action
1415 kwargs_omci_test_action = {
1416 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1417 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1418 }
1419 serial_number = device.serial_number
1420 self._test_request = OmciTestRequest(self.core_proxy,
1421 self.omci_agent, self.device_id,
1422 AniG, serial_number,
1423 self.logical_device_id,
1424 exclusive=False,
1425 **kwargs_omci_test_action)
1426
1427 self.enabled = True
1428 else:
1429 self.logger.info('onu-already-activated')
1430 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001431
dbainbri4d3a0dc2020-12-02 00:33:42 +00001432 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001433}
1434
1435// doStateConnected get the device info and update to voltha core
1436// for comparison of the original method (not that easy to uncomment): compare here:
1437// voltha-openolt-adapter/adaptercore/device_handler.go
1438// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440
dbainbri4d3a0dc2020-12-02 00:33:42 +00001441 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301442 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001443 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001445}
1446
1447// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001449
dbainbri4d3a0dc2020-12-02 00:33:42 +00001450 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301451 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001453 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454
1455 /*
1456 // Synchronous call to update device state - this method is run in its own go routine
1457 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1458 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001459 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 +00001460 return err
1461 }
1462 return nil
1463 */
1464}
1465
1466// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001468
dbainbri4d3a0dc2020-12-02 00:33:42 +00001469 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001470 var err error
1471
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001472 device := dh.device
1473 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001474 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001476 e.Cancel(err)
1477 return
1478 }
1479
1480 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001482 /*
1483 // Update the all ports state on that device to disable
1484 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001485 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001486 return er
1487 }
1488
1489 //Update the device oper state and connection status
1490 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1491 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1492 dh.device = cloned
1493
1494 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001495 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001496 return er
1497 }
1498
1499 //get the child device for the parent device
1500 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1501 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001502 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001503 return err
1504 }
1505 for _, onuDevice := range onuDevices.Items {
1506
1507 // Update onu state as down in onu adapter
1508 onuInd := oop.OnuIndication{}
1509 onuInd.OperState = "down"
1510 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1511 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1512 if er != nil {
1513 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001514 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001515 //Do not return here and continue to process other ONUs
1516 }
1517 }
1518 // * Discovered ONUs entries need to be cleared , since after OLT
1519 // is up, it starts sending discovery indications again* /
1520 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001521 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001522 return nil
1523 */
Himani Chawla4d908332020-08-31 12:30:20 +05301524 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001525 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001526 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001527}
1528
Himani Chawla6d2ae152020-09-02 13:11:20 +05301529// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530// #################################################################################
1531
1532// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301533// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001534
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001535//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001537 dh.lockDevice.RLock()
1538 pOnuDeviceEntry := dh.pOnuOmciDevice
1539 if aWait && pOnuDeviceEntry == nil {
1540 //keep the read sema short to allow for subsequent write
1541 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001543 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1544 // so it might be needed to wait here for that event with some timeout
1545 select {
1546 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001548 return nil
1549 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001551 // if written now, we can return the written value without sema
1552 return dh.pOnuOmciDevice
1553 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001554 }
mpagenko3af1f032020-06-10 08:53:41 +00001555 dh.lockDevice.RUnlock()
1556 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001557}
1558
Himani Chawla6d2ae152020-09-02 13:11:20 +05301559//setOnuDeviceEntry sets the ONU device entry within the handler
1560func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001561 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001562 dh.lockDevice.Lock()
1563 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001564 dh.pOnuOmciDevice = apDeviceEntry
1565 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001566 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301567 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001568 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001569}
1570
Himani Chawla6d2ae152020-09-02 13:11:20 +05301571//addOnuDeviceEntry creates a new ONU device or returns the existing
1572func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001574
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001576 if deviceEntry == nil {
1577 /* costum_me_map in python code seems always to be None,
1578 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1579 /* also no 'clock' argument - usage open ...*/
1580 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001581 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001582 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001583 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301584 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001585 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001586 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001587 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001588 // fire deviceEntry ready event to spread to possibly waiting processing
1589 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001591 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001593 }
1594 // might be updated with some error handling !!!
1595 return nil
1596}
1597
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1599 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001600 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1601
1602 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001603
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001605 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001607 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1608 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001609 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 if err := dh.storePersistentData(ctx); err != nil {
1611 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001612 log.Fields{"device-id": dh.deviceID, "err": err})
1613 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001615 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001617 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1618 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001620 }
1621 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001623 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001624
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001625 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001626 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001627 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 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 +00001629 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001630 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001631 } else {
1632 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001633 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001635 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1636 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1637 // 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 +00001638 // 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 +00001639 // so let's just try to keep it simple ...
1640 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001642 if err != nil || device == nil {
1643 //TODO: needs to handle error scenarios
1644 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1645 return errors.New("Voltha Device not found")
1646 }
1647 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001650 return err
mpagenko3af1f032020-06-10 08:53:41 +00001651 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001652
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001653 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654
1655 /* this might be a good time for Omci Verify message? */
1656 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001658 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001659 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661
1662 /* give the handler some time here to wait for the OMCi verification result
1663 after Timeout start and try MibUpload FSM anyway
1664 (to prevent stopping on just not supported OMCI verification from ONU) */
1665 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001666 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001670 }
1671
1672 /* In py code it looks earlier (on activate ..)
1673 # Code to Run OMCI Test Action
1674 kwargs_omci_test_action = {
1675 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1676 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1677 }
1678 serial_number = device.serial_number
1679 self._test_request = OmciTestRequest(self.core_proxy,
1680 self.omci_agent, self.device_id,
1681 AniG, serial_number,
1682 self.logical_device_id,
1683 exclusive=False,
1684 **kwargs_omci_test_action)
1685 ...
1686 # Start test requests after a brief pause
1687 if not self._test_request_started:
1688 self._test_request_started = True
1689 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1690 reactor.callLater(tststart, self._test_request.start_collector)
1691
1692 */
1693 /* which is then: in omci_test_request.py : */
1694 /*
1695 def start_collector(self, callback=None):
1696 """
1697 Start the collection loop for an adapter if the frequency > 0
1698
1699 :param callback: (callable) Function to call to collect PM data
1700 """
1701 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1702 if callback is None:
1703 callback = self.perform_test_omci
1704
1705 if self.lc is None:
1706 self.lc = LoopingCall(callback)
1707
1708 if self.default_freq > 0:
1709 self.lc.start(interval=self.default_freq / 10)
1710
1711 def perform_test_omci(self):
1712 """
1713 Perform the initial test request
1714 """
1715 ani_g_entities = self._device.configuration.ani_g_entities
1716 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1717 is not None else None
1718 self._entity_id = ani_g_entities_ids[0]
1719 self.logger.info('perform-test', entity_class=self._entity_class,
1720 entity_id=self._entity_id)
1721 try:
1722 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1723 result = yield self._device.omci_cc.send(frame)
1724 if not result.fields['omci_message'].fields['success_code']:
1725 self.logger.info('Self-Test Submitted Successfully',
1726 code=result.fields[
1727 'omci_message'].fields['success_code'])
1728 else:
1729 raise TestFailure('Test Failure: {}'.format(
1730 result.fields['omci_message'].fields['success_code']))
1731 except TimeoutError as e:
1732 self.deferred.errback(failure.Failure(e))
1733
1734 except Exception as e:
1735 self.logger.exception('perform-test-Error', e=e,
1736 class_id=self._entity_class,
1737 entity_id=self._entity_id)
1738 self.deferred.errback(failure.Failure(e))
1739
1740 */
1741
1742 // PM related heartbeat??? !!!TODO....
1743 //self._heartbeat.enabled = True
1744
mpagenko1cc3cb42020-07-27 15:24:38 +00001745 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1746 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1747 * 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 +05301748 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001749 */
1750 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001751 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001752 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001753 if pMibUlFsm.Is(ulStDisabled) {
1754 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 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 +00001756 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301757 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301759 //Determine ONU status and start/re-start MIB Synchronization tasks
1760 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001761 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301762 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 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 +00001764 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001765 }
Himani Chawla4d908332020-08-31 12:30:20 +05301766 } else {
1767 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 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 +00001769 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301770 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001772 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001773 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001775 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001776 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001777 }
1778 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001780 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001781 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001782
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001783 if !dh.getCollectorIsRunning() {
1784 // Start PM collector routine
1785 go dh.startCollector(ctx)
1786 }
Himani Chawla1472c682021-03-17 17:11:14 +05301787 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301788 go dh.startAlarmManager(ctx)
1789 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301790
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791 return nil
1792}
1793
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001795 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001796 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001797 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001799
mpagenko900ee4b2020-10-12 11:56:34 +00001800 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1801 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1802 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001803 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001805 log.Fields{"device-id": dh.deviceID, "error": err})
1806 // abort: system behavior is just unstable ...
1807 return err
1808 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001809 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 _ = 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 +00001811
1812 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1813 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1814 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001816 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001818 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001819 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001821
1822 //TODO!!! remove existing traffic profiles
1823 /* from py code, if TP's exist, remove them - not yet implemented
1824 self._tp = dict()
1825 # Let TP download happen again
1826 for uni_id in self._tp_service_specific_task:
1827 self._tp_service_specific_task[uni_id].clear()
1828 for uni_id in self._tech_profile_download_done:
1829 self._tech_profile_download_done[uni_id].clear()
1830 */
1831
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001833
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001834 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001835
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001837 // abort: system behavior is just unstable ...
1838 return err
1839 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001841 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001843 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001844 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001846 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001847 // abort: system behavior is just unstable ...
1848 return err
1849 }
1850 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001852 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001853 return nil
1854}
1855
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001856func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001857 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1858 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1859 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1860 // and using the stop/reset event should never harm
1861
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001863 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001865 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1866 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001867 if pDevEntry.PDevOmciCC != nil {
1868 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1869 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001870 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001871 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001872 }
1873 //MibDownload may run
1874 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1875 if pMibDlFsm != nil {
1876 _ = pMibDlFsm.Event(dlEvReset)
1877 }
1878 //port lock/unlock FSM's may be active
1879 if dh.pUnlockStateFsm != nil {
1880 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1881 }
1882 if dh.pLockStateFsm != nil {
1883 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1884 }
1885 //techProfile related PonAniConfigFsm FSM may be active
1886 if dh.pOnuTP != nil {
1887 // should always be the case here
1888 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1889 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001890 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001891 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001892 }
mpagenko900ee4b2020-10-12 11:56:34 +00001893 }
1894 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001895 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001896 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001897 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1898 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001899 dh.lockVlanConfig.RUnlock()
1900 //reset of all Fsm is always accompanied by global persistency data removal
1901 // no need to remove specific data
1902 pVlanFilterFsm.RequestClearPersistency(false)
1903 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001904 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001905 } else {
1906 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001907 }
1908 }
1909 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001910 if dh.getCollectorIsRunning() {
1911 // Stop collector routine
1912 dh.stopCollector <- true
1913 }
Himani Chawla1472c682021-03-17 17:11:14 +05301914 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301915 dh.stopAlarmManager <- true
1916 }
1917
mpagenko80622a52021-02-09 16:53:23 +00001918 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00001919 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00001920 dh.lockUpgradeFsm.RLock()
1921 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001922 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00001923 }
1924 dh.lockUpgradeFsm.RUnlock()
1925
mpagenko7d6bb022021-03-11 15:07:55 +00001926 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001927 return nil
1928}
1929
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1931 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 +05301932
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001933 // store persistent data collected during MIB upload processing
1934 if err := dh.storePersistentData(ctx); err != nil {
1935 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1936 log.Fields{"device-id": dh.deviceID, "err": err})
1937 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001938 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001939 dh.addAllUniPorts(ctx)
1940
mpagenkoa40e99a2020-11-17 13:50:39 +00001941 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1942 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1943 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1944 * disable/enable toggling here to allow traffic
1945 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1946 * like the py comment says:
1947 * # start by locking all the unis till mib sync and initial mib is downloaded
1948 * # this way we can capture the port down/up events when we are ready
1949 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301950
mpagenkoa40e99a2020-11-17 13:50:39 +00001951 // Init Uni Ports to Admin locked state
1952 // *** should generate UniLockStateDone event *****
1953 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001955 } else { //LockStateFSM already init
1956 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001958 }
1959}
1960
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1962 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301963 /* Mib download procedure -
1964 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1965 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001967 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001968 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001969 return
1970 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301971 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1972 if pMibDlFsm != nil {
1973 if pMibDlFsm.Is(dlStDisabled) {
1974 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 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 +05301976 // maybe try a FSM reset and then again ... - TODO!!!
1977 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301979 // maybe use more specific states here for the specific download steps ...
1980 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301982 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301984 //Begin MIB data download (running autonomously)
1985 }
1986 }
1987 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001989 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301990 // maybe try a FSM reset and then again ... - TODO!!!
1991 }
1992 /***** Mib download started */
1993 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301995 }
1996}
1997
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1999 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302000 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002001 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002003 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002004 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2005 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2006 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2007 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302009 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2010 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302012 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302014 }
2015 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302017 log.Fields{"device-id": dh.deviceID})
2018 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002019 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002020
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002021 if !dh.getCollectorIsRunning() {
2022 // Start PM collector routine
2023 go dh.startCollector(ctx)
2024 }
2025 if !dh.getAlarmManagerIsRunning(ctx) {
2026 go dh.startAlarmManager(ctx)
2027 }
2028
Girish Gowdrae0140f02021-02-02 16:55:09 -08002029 // Initialize classical L2 PM Interval Counters
2030 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2031 // There is no way we should be landing here, but if we do then
2032 // there is nothing much we can do about this other than log error
2033 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2034 }
2035
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002036 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002037
2038 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2039 if pDevEntry == nil {
2040 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2041 return
2042 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002043 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002044 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002045 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002046 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2047 log.Fields{"device-id": dh.deviceID})
2048 go dh.reconcileDeviceTechProf(ctx)
2049 // reconcilement will be continued after ani config is done
2050 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002051 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002052 // *** should generate UniUnlockStateDone event *****
2053 if dh.pUnlockStateFsm == nil {
2054 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2055 } else { //UnlockStateFSM already init
2056 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2057 dh.runUniLockFsm(ctx, false)
2058 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302059 }
2060}
2061
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2063 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302064
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002065 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302067 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2069 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002070 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002072 return
2073 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002074 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002075 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002076 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077 if err := dh.storePersistentData(ctx); err != nil {
2078 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002079 log.Fields{"device-id": dh.deviceID, "err": err})
2080 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302081 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 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 +05302083 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002085 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302086 }
2087}
2088
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2090 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002091 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002092 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002093 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2094 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002095 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002096 }
2097
dbainbri4d3a0dc2020-12-02 00:33:42 +00002098 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002099 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002100 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002101
2102 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002104
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002106 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002108 return
2109 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002110 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002111 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002112 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113 if err := dh.storePersistentData(ctx); err != nil {
2114 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002115 log.Fields{"device-id": dh.deviceID, "err": err})
2116 }
mpagenko900ee4b2020-10-12 11:56:34 +00002117}
2118
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2120 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002121 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002122 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002123 voltha.OperStatus_ACTIVE); err != nil {
2124 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002126 }
2127
dbainbri4d3a0dc2020-12-02 00:33:42 +00002128 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002129 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002130 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002131 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002132
2133 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002135
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002137 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002139 return
2140 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002141 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002142 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002143 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 if err := dh.storePersistentData(ctx); err != nil {
2145 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002146 log.Fields{"device-id": dh.deviceID, "err": err})
2147 }
mpagenko900ee4b2020-10-12 11:56:34 +00002148}
2149
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002151 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002153 // attention: the device reason update is done based on ONU-UNI-Port related activity
2154 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002155 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002156 // 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 +00002157 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302158 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002159 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002161 }
2162 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002164 // attention: the device reason update is done based on ONU-UNI-Port related activity
2165 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002166 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002167 // 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 +00002168 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002169 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002170 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302171}
2172
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2174 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002175 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302176 // attention: the device reason update is done based on ONU-UNI-Port related activity
2177 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302178
mpagenkof1fc3862021-02-16 10:09:52 +00002179 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002180 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002181 // which may be the case from some previous actvity on another UNI Port of the ONU
2182 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002183 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2184 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002185 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002186 }
2187 }
2188 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002189 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002190 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002192 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302193 }
mpagenkof1fc3862021-02-16 10:09:52 +00002194
2195 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2196 //events that request KvStore write
2197 if err := dh.storePersistentData(ctx); err != nil {
2198 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2199 log.Fields{"device-id": dh.deviceID, "err": err})
2200 }
2201 } else {
2202 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2203 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002204 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302205}
2206
Himani Chawla6d2ae152020-09-02 13:11:20 +05302207//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302209 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002210 case MibDatabaseSync:
2211 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002213 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002214 case UniLockStateDone:
2215 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002217 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002218 case MibDownloadDone:
2219 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002220 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002221 }
2222 case UniUnlockStateDone:
2223 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002225 }
mpagenko900ee4b2020-10-12 11:56:34 +00002226 case UniEnableStateDone:
2227 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002229 }
2230 case UniDisableStateDone:
2231 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002232 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002233 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002234 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002235 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002237 }
mpagenkof1fc3862021-02-16 10:09:52 +00002238 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002239 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002241 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002242 default:
2243 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002245 }
2246 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002247}
2248
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002250 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002251 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302252 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002253 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002254 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002255 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302256 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002257 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002258 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002260 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002261 //store UniPort with the System-PortNumber key
2262 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002263 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002264 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2266 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002267 } //error logging already within UniPort method
2268 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002270 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002271 }
2272 }
2273}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002274
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002275func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2276 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2277 if pDevEntry == nil {
2278 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2279 return
2280 }
2281 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2282 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2283 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2284 for _, mgmtEntityID := range pptpInstKeys {
2285 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2286 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2287 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2288 i++
2289 }
2290 } else {
2291 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2292 }
2293 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2294 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2295 for _, mgmtEntityID := range veipInstKeys {
2296 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2297 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2298 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2299 i++
2300 }
2301 } else {
2302 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2303 }
2304 if i == 0 {
2305 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2306 }
2307}
2308
mpagenko3af1f032020-06-10 08:53:41 +00002309// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002311 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302312 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002313 // with following remark:
2314 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2315 // # load on the core
2316
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002317 // 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 +00002318
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002319 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002320 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302321 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002322 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302323 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002324 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002325 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 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 +00002327 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002329 }
mpagenko3af1f032020-06-10 08:53:41 +00002330 }
2331 }
2332}
2333
2334// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002336 // compare enableUniPortStateUpdate() above
2337 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2338 for uniNo, uniPort := range dh.uniEntityMap {
2339 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302340 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002341 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302342 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002343 if !dh.isReconciling() {
2344 //maybe also use getter functions on uniPort - perhaps later ...
2345 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2346 } else {
2347 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2348 }
2349
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002350 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002351 }
2352}
2353
2354// ONU_Active/Inactive announcement on system KAFKA bus
2355// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002357 var de voltha.DeviceEvent
2358 eventContext := make(map[string]string)
2359 //Populating event context
2360 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002362 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302364 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002365 }
2366 oltSerialNumber := parentDevice.SerialNumber
2367
2368 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2369 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2370 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302371 eventContext["olt-serial-number"] = oltSerialNumber
2372 eventContext["device-id"] = aDeviceID
2373 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002375 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002376
2377 /* Populating device event body */
2378 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302379 de.ResourceId = aDeviceID
2380 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002381 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2382 de.Description = fmt.Sprintf("%s Event - %s - %s",
2383 cEventObjectType, cOnuActivatedEvent, "Raised")
2384 } else {
2385 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2386 de.Description = fmt.Sprintf("%s Event - %s - %s",
2387 cEventObjectType, cOnuActivatedEvent, "Cleared")
2388 }
2389 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2391 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302392 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002393 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302395 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002396}
2397
Himani Chawla4d908332020-08-31 12:30:20 +05302398// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002400 chLSFsm := make(chan Message, 2048)
2401 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302402 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002404 sFsmName = "LockStateFSM"
2405 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002406 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002407 sFsmName = "UnLockStateFSM"
2408 }
mpagenko3af1f032020-06-10 08:53:41 +00002409
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002411 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002413 return
2414 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002416 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002417 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302418 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002419 dh.pLockStateFsm = pLSFsm
2420 } else {
2421 dh.pUnlockStateFsm = pLSFsm
2422 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002424 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002425 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002426 }
2427}
2428
2429// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002431 /* Uni Port lock/unlock procedure -
2432 ***** should run via 'adminDone' state and generate the argument requested event *****
2433 */
2434 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302435 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002436 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2437 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2438 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002439 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302440 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002441 }
2442 } else {
2443 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2444 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2445 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002446 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302447 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002448 }
2449 }
2450 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002451 if pLSStatemachine.Is(uniStDisabled) {
2452 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002454 // maybe try a FSM reset and then again ... - TODO!!!
2455 } else {
2456 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002458 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002459 }
2460 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002462 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002463 // maybe try a FSM reset and then again ... - TODO!!!
2464 }
2465 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002466 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002467 // maybe try a FSM reset and then again ... - TODO!!!
2468 }
2469}
2470
mpagenko80622a52021-02-09 16:53:23 +00002471// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002472func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002473 //in here lockUpgradeFsm is already locked
2474 chUpgradeFsm := make(chan Message, 2048)
2475 var sFsmName = "OnuSwUpgradeFSM"
2476 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002477 if apDevEntry.PDevOmciCC == nil {
2478 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2479 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002480 }
mpagenko15ff4a52021-03-02 10:09:20 +00002481 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002482 sFsmName, chUpgradeFsm)
2483 if dh.pOnuUpradeFsm != nil {
2484 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2485 if pUpgradeStatemachine != nil {
2486 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2487 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2488 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2489 // maybe try a FSM reset and then again ... - TODO!!!
2490 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2491 }
2492 /***** LockStateFSM started */
2493 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2494 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2495 } else {
2496 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2497 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2498 // maybe try a FSM reset and then again ... - TODO!!!
2499 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2500 }
2501 } else {
2502 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2503 // maybe try a FSM reset and then again ... - TODO!!!
2504 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2505 }
2506 } else {
2507 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2508 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2509 }
2510 return nil
2511}
2512
2513// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2514func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2515 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2516 "device-id": dh.deviceID})
2517 dh.lockUpgradeFsm.Lock()
2518 defer dh.lockUpgradeFsm.Unlock()
2519 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2520}
2521
mpagenko15ff4a52021-03-02 10:09:20 +00002522// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2523func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2524 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2525 if pDevEntry == nil {
2526 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2527 return
2528 }
2529
2530 dh.lockUpgradeFsm.RLock()
2531 defer dh.lockUpgradeFsm.RUnlock()
2532 if dh.pOnuUpradeFsm != nil {
2533 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2534 if pUpgradeStatemachine != nil {
2535 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2536 // (some manual forced commit could do without)
2537 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002538 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002539 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2540 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2541 return
2542 }
2543 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2544 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2545 } else {
2546 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2547 log.Fields{"device-id": dh.deviceID})
2548 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2549 return
2550 }
2551 }
2552 }
2553 } else {
2554 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2555 }
2556}
2557
Himani Chawla6d2ae152020-09-02 13:11:20 +05302558//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002560
2561 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002562 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002563 kvbackend := &db.Backend{
2564 Client: dh.pOpenOnuAc.kvClient,
2565 StoreType: dh.pOpenOnuAc.KVStoreType,
2566 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002567 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002568 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2569 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002570
mpagenkoaf801632020-07-03 10:00:42 +00002571 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002572}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302574 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002575
mpagenkodff5dda2020-08-28 11:52:01 +00002576 for _, field := range flow.GetOfbFields(apFlowItem) {
2577 switch field.Type {
2578 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2579 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002580 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002581 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2582 }
mpagenko01e726e2020-10-23 09:45:29 +00002583 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002584 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2585 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302586 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002587 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302588 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2589 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002590 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2591 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002592 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2593 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302594 return
mpagenkodff5dda2020-08-28 11:52:01 +00002595 }
2596 }
mpagenko01e726e2020-10-23 09:45:29 +00002597 */
mpagenkodff5dda2020-08-28 11:52:01 +00002598 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2599 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302600 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002601 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302602 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002603 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302604 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002605 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302607 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002608 }
2609 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2610 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302611 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002613 "PCP": loAddPcp})
2614 }
2615 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2616 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002617 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002618 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2619 }
2620 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2621 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002623 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2624 }
2625 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2626 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002628 "IPv4-DST": field.GetIpv4Dst()})
2629 }
2630 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2631 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002633 "IPv4-SRC": field.GetIpv4Src()})
2634 }
2635 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2636 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002637 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002638 "Metadata": field.GetTableMetadata()})
2639 }
2640 /*
2641 default:
2642 {
2643 //all other entires ignored
2644 }
2645 */
2646 }
2647 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302648}
mpagenkodff5dda2020-08-28 11:52:01 +00002649
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002651 for _, action := range flow.GetActions(apFlowItem) {
2652 switch action.Type {
2653 /* not used:
2654 case of.OfpActionType_OFPAT_OUTPUT:
2655 {
mpagenko01e726e2020-10-23 09:45:29 +00002656 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002657 "Output": action.GetOutput()})
2658 }
2659 */
2660 case of.OfpActionType_OFPAT_PUSH_VLAN:
2661 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002662 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002663 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2664 }
2665 case of.OfpActionType_OFPAT_SET_FIELD:
2666 {
2667 pActionSetField := action.GetSetField()
2668 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002669 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002670 "OxcmClass": pActionSetField.Field.OxmClass})
2671 }
2672 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302673 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002674 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302675 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002676 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302677 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002678 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302679 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002680 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002681 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002682 "Type": pActionSetField.Field.GetOfbField().Type})
2683 }
2684 }
2685 /*
2686 default:
2687 {
2688 //all other entires ignored
2689 }
2690 */
2691 }
2692 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302693}
2694
2695//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002696func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302697 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2698 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2699 var loAddPcp, loSetPcp uint8
2700 var loIPProto uint32
2701 /* the TechProfileId is part of the flow Metadata - compare also comment within
2702 * OLT-Adapter:openolt_flowmgr.go
2703 * Metadata 8 bytes:
2704 * Most Significant 2 Bytes = Inner VLAN
2705 * Next 2 Bytes = Tech Profile ID(TPID)
2706 * Least Significant 4 Bytes = Port ID
2707 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2708 * subscriber related flows.
2709 */
2710
dbainbri4d3a0dc2020-12-02 00:33:42 +00002711 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302712 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302714 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002715 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302716 }
mpagenko551a4d42020-12-08 18:09:20 +00002717 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002718 loCookie := apFlowItem.GetCookie()
2719 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002720 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002721 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302722
dbainbri4d3a0dc2020-12-02 00:33:42 +00002723 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002724 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302725 if loIPProto == 2 {
2726 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2727 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002728 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2729 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302730 return nil
2731 }
mpagenko01e726e2020-10-23 09:45:29 +00002732 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002733 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002734
2735 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002736 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002737 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2738 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2739 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2740 //TODO!!: Use DeviceId within the error response to rwCore
2741 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002742 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002743 }
2744 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002745 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002746 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2747 } else {
2748 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2749 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2750 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302751 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002752 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002753 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002754 }
mpagenko9a304ea2020-12-16 15:54:01 +00002755
2756 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002757 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002758 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302759 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002760 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002761 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002762 dh.lockVlanConfig.RUnlock()
2763 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002764 }
mpagenkof1fc3862021-02-16 10:09:52 +00002765 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002766 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002767 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002768}
2769
2770//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002771func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002772 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2773 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2774 //no extra check is done on the rule parameters
2775 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2776 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2777 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2778 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002779 // - 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 +00002780 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002781 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002782
2783 /* TT related temporary workaround - should not be needed anymore
2784 for _, field := range flow.GetOfbFields(apFlowItem) {
2785 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2786 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002787 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002788 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2789 if loIPProto == 2 {
2790 // 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 +00002791 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002792 log.Fields{"device-id": dh.deviceID})
2793 return nil
2794 }
2795 }
2796 } //for all OfbFields
2797 */
2798
mpagenko9a304ea2020-12-16 15:54:01 +00002799 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002800 dh.lockVlanConfig.RLock()
2801 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002802 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002803 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002804 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002806 log.Fields{"device-id": dh.deviceID})
2807 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002808 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002810
mpagenko01e726e2020-10-23 09:45:29 +00002811 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002812}
2813
Himani Chawla26e555c2020-08-31 12:30:20 +05302814// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002815// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002816func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002817 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002818 chVlanFilterFsm := make(chan Message, 2048)
2819
dbainbri4d3a0dc2020-12-02 00:33:42 +00002820 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002821 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302823 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002824 }
2825
dbainbri4d3a0dc2020-12-02 00:33:42 +00002826 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002827 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002828 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002829 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002830 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002831 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2832 // (from parallel processing)
2833 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302834 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002835 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2836 if pVlanFilterStatemachine != nil {
2837 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2838 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302840 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002841 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302842 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002843 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302844 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2845 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002846 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002848 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302849 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002850 }
2851 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002852 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002853 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302854 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002855 }
2856 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002857 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002858 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302859 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002860 }
2861 return nil
2862}
2863
mpagenkofc4f56e2020-11-04 17:17:49 +00002864//VerifyVlanConfigRequest checks on existence of a given uniPort
2865// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002866func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002867 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2868 var pCurrentUniPort *onuUniPort
2869 for _, uniPort := range dh.uniEntityMap {
2870 // only if this port is validated for operState transfer
2871 if uniPort.uniID == uint8(aUniID) {
2872 pCurrentUniPort = uniPort
2873 break //found - end search loop
2874 }
2875 }
2876 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002877 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002878 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2879 return
2880 }
mpagenko551a4d42020-12-08 18:09:20 +00002881 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002882}
2883
mpagenkodff5dda2020-08-28 11:52:01 +00002884//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002885func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002886 //TODO!! verify and start pending flow configuration
2887 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2888 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002889
2890 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302891 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002892 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002893 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2894 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2895 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002896 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2897 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2898 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2899 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2900 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2901 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2902 } else {
2903 /***** UniVlanConfigFsm continued */
2904 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2905 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2906 "UniPort": apUniPort.portNo})
2907 }
2908 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2909 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2910 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2911 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2912 } else {
2913 /***** UniVlanConfigFsm continued */
2914 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2915 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2916 "UniPort": apUniPort.portNo})
2917 }
mpagenkodff5dda2020-08-28 11:52:01 +00002918 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002919 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2920 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002921 "UniPort": apUniPort.portNo})
2922 }
2923 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002924 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2925 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2926 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002927 }
2928 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002929 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002930 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002931 }
mpagenkof1fc3862021-02-16 10:09:52 +00002932 } else {
2933 dh.lockVlanConfig.RUnlock()
2934 }
mpagenkodff5dda2020-08-28 11:52:01 +00002935}
2936
2937//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2938// 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 +00002939func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2940 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002941 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2942 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002943 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302944 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002945 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002946}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002947
mpagenkof1fc3862021-02-16 10:09:52 +00002948//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2949func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2950 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2951 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2952 // obviously then parallel processing on the cancel must be avoided
2953 // deadline context to ensure completion of background routines waited for
2954 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2955 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2956 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2957
2958 aPDevEntry.resetKvProcessingErrorIndication()
2959 var wg sync.WaitGroup
2960 wg.Add(1) // for the 1 go routine to finish
2961
2962 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2963 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2964
2965 return aPDevEntry.getKvProcessingErrorIndication()
2966}
2967
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002968//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2969//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002970func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2971 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002972
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002973 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002974 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002975 return nil
2976 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002977 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002978
dbainbri4d3a0dc2020-12-02 00:33:42 +00002979 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002980 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002981 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002982 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2983 }
2984 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2985
mpagenkof1fc3862021-02-16 10:09:52 +00002986 if aWriteToKvStore {
2987 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2988 }
2989 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002990}
2991
dbainbri4d3a0dc2020-12-02 00:33:42 +00002992func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002993 defer cancel() //ensure termination of context (may be pro forma)
2994 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002995 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002996 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002997}
2998
dbainbri4d3a0dc2020-12-02 00:33:42 +00002999func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003000
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003001 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003002 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003003 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3005 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003006 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003007 return err
3008 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003009 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003010 return nil
3011 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003012 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003013 return nil
3014}
3015
dbainbri4d3a0dc2020-12-02 00:33:42 +00003016func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3017 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003018 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003019 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003020 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3021 }
mpagenkof1fc3862021-02-16 10:09:52 +00003022 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003023}
3024
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003025func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3026 var errStr string = ""
3027 for _, err := range errS {
3028 if err != nil {
3029 errStr = errStr + err.Error() + " "
3030 }
3031 }
3032 if errStr != "" {
3033 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3034 }
3035 return nil
3036}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003037
3038// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
3039func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3040 dh.lockDevice.RLock()
3041 defer dh.lockDevice.RUnlock()
3042 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3043 return uniPort.entityID, nil
3044 }
3045 return 0, errors.New("error-fetching-uni-port")
3046}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003047
3048// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003049func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3050 var errorsList []error
3051 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 -08003052
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003053 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3054 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3055 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3056
3057 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3058 // successfully.
3059 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3060 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3061 if len(errorsList) > 0 {
3062 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3063 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003064 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003065 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3066 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003067}
3068
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003069func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3070 var err error
3071 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003072 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003073
3074 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3075 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3076 errorsList = append(errorsList, err)
3077 }
3078 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003079 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003080
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003081 return errorsList
3082}
3083
3084func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3085 var err error
3086 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003087 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003088 // Check if group metric related config is updated
3089 for _, v := range pmConfigs.Groups {
3090 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3091 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3092 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3093
3094 if ok && m.frequency != v.GroupFreq {
3095 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3096 errorsList = append(errorsList, err)
3097 }
3098 }
3099 if ok && m.enabled != v.Enabled {
3100 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3101 errorsList = append(errorsList, err)
3102 }
3103 }
3104 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003105 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003106 return errorsList
3107}
3108
3109func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3110 var err error
3111 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003112 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003113 // Check if standalone metric related config is updated
3114 for _, v := range pmConfigs.Metrics {
3115 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003116 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003117 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3118
3119 if ok && m.frequency != v.SampleFreq {
3120 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3121 errorsList = append(errorsList, err)
3122 }
3123 }
3124 if ok && m.enabled != v.Enabled {
3125 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3126 errorsList = append(errorsList, err)
3127 }
3128 }
3129 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003130 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003131 return errorsList
3132}
3133
3134// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003135func (dh *deviceHandler) startCollector(ctx context.Context) {
3136 logger.Debugf(ctx, "startingCollector")
3137
3138 // Start routine to process OMCI GET Responses
3139 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003140 // Initialize the next metric collection time.
3141 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3142 // reset like onu rebooted.
3143 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003144 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003145 for {
3146 select {
3147 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003148 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003149 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003150 // Stop the L2 PM FSM
3151 go func() {
3152 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3153 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3154 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3155 }
3156 } else {
3157 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3158 }
3159 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003160 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3161 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3162 }
3163 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3164 dh.pOnuMetricsMgr.stopTicks <- true
3165 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003166
Girish Gowdrae09a6202021-01-12 18:10:59 -08003167 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003168 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3169 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3170 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3171 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3172 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003173 // Update the next metric collection time.
3174 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003175 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003176 } else {
3177 if dh.pmConfigs.Grouped { // metrics are managed as a group
3178 // parse through the group and standalone metrics to see it is time to collect their metrics
3179 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003180
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003181 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3182 // 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 -08003183 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3184 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003185 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3186 }
3187 }
3188 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3189 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3190 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3191 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3192 }
3193 }
3194 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3195
3196 // parse through the group and update the next metric collection time
3197 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3198 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3199 // 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 -08003200 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3201 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003202 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3203 }
3204 }
3205 // parse through the standalone metrics and update the next metric collection time
3206 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3207 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3208 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3209 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3210 }
3211 }
3212 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3213 } /* else { // metrics are not managed as a group
3214 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3215 } */
3216 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003217 }
3218 }
3219}
kesavandfdf77632021-01-26 23:40:33 -05003220
3221func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3222
3223 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3224 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3225}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003226
mpagenkof1fc3862021-02-16 10:09:52 +00003227func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3228 if pFsm == nil {
3229 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003230 }
mpagenkof1fc3862021-02-16 10:09:52 +00003231 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003232}
3233
mpagenkof1fc3862021-02-16 10:09:52 +00003234func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3235 var pFsm *fsm.FSM
3236 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3237 switch omciFsm {
3238 case cUploadFsm:
3239 {
3240 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3241 }
3242 case cDownloadFsm:
3243 {
3244 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3245 }
3246 case cUniLockFsm:
3247 {
3248 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3249 }
3250 case cUniUnLockFsm:
3251 {
3252 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3253 }
3254 case cL2PmFsm:
3255 {
3256 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3257 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3258 } else {
3259 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003260 }
3261 }
mpagenko80622a52021-02-09 16:53:23 +00003262 case cOnuUpgradeFsm:
3263 {
3264 dh.lockUpgradeFsm.RLock()
3265 defer dh.lockUpgradeFsm.RUnlock()
3266 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3267 }
mpagenkof1fc3862021-02-16 10:09:52 +00003268 default:
3269 {
3270 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3271 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3272 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003273 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003274 }
mpagenkof1fc3862021-02-16 10:09:52 +00003275 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003276}
3277
mpagenkof1fc3862021-02-16 10:09:52 +00003278func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3279 for _, v := range dh.pOnuTP.pAniConfigFsm {
3280 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003281 return false
3282 }
3283 }
3284 return true
3285}
3286
mpagenkof1fc3862021-02-16 10:09:52 +00003287func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3288 dh.lockVlanConfig.RLock()
3289 defer dh.lockVlanConfig.RUnlock()
3290 for _, v := range dh.UniVlanConfigFsmMap {
3291 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3292 return false
3293 }
3294 }
3295 return true //FSM not active - so there is no activity on omci
3296}
3297
3298func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3299 dh.lockVlanConfig.RLock()
3300 defer dh.lockVlanConfig.RUnlock()
3301 for _, v := range dh.UniVlanConfigFsmMap {
3302 if v.pAdaptFsm.pFsm != nil {
3303 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3304 return true //there is at least one VLAN FSM with some active configuration
3305 }
3306 }
3307 }
3308 return false //there is no VLAN FSM with some active configuration
3309}
3310
3311func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3312 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3313 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3314 return false
3315 }
3316 }
3317 // a further check is done to identify, if at least some data traffic related configuration exists
3318 // 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])
3319 return dh.checkUserServiceExists(ctx)
3320}
3321
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003322func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3323 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3324 if err := dh.resetFsms(ctx, false); err != nil {
3325 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3326 // TODO: fatal error reset ONU, delete deviceHandler!
3327 return
3328 }
3329 if !dh.getCollectorIsRunning() {
3330 // Start PM collector routine
3331 go dh.startCollector(ctx)
3332 }
Himani Chawla1472c682021-03-17 17:11:14 +05303333 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303334 go dh.startAlarmManager(ctx)
3335 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003336 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003337 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003338}
3339
3340func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3341 dh.mutexCollectorFlag.Lock()
3342 dh.collectorIsRunning = flagValue
3343 dh.mutexCollectorFlag.Unlock()
3344}
3345
3346func (dh *deviceHandler) getCollectorIsRunning() bool {
3347 dh.mutexCollectorFlag.RLock()
3348 flagValue := dh.collectorIsRunning
3349 dh.mutexCollectorFlag.RUnlock()
3350 return flagValue
3351}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303352
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303353func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3354 dh.mutextAlarmManagerFlag.Lock()
3355 dh.alarmManagerIsRunning = flagValue
3356 dh.mutextAlarmManagerFlag.Unlock()
3357}
3358
Himani Chawla1472c682021-03-17 17:11:14 +05303359func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303360 dh.mutextAlarmManagerFlag.RLock()
3361 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303362 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303363 dh.mutextAlarmManagerFlag.RUnlock()
3364 return flagValue
3365}
3366
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303367func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3368 logger.Debugf(ctx, "startingAlarmManager")
3369
3370 // Start routine to process OMCI GET Responses
3371 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303372 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303373 if stop := <-dh.stopAlarmManager; stop {
3374 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303375 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303376 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303377 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3378 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3379 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303380 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303381 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303382 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3383 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303384 }
3385}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003386
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003387func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003388 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003389
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003390 if !dh.isReconciling() {
3391 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003392 logger.Debugw(ctx, "wait for channel signal or timeout",
3393 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003394 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003395 case success := <-dh.chReconcilingFinished:
3396 if success {
Maninderb5187552021-03-23 22:23:42 +05303397 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3398 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3399 log.Fields{"device-id": dh.deviceID})
3400 } else {
3401 connectStatus := voltha.ConnectStatus_UNREACHABLE
3402 operState := voltha.OperStatus_UNKNOWN
3403 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3404 connectStatus = voltha.ConnectStatus_REACHABLE
3405 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3406 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3407 operState = voltha.OperStatus_ACTIVE
3408 } else {
3409 operState = voltha.OperStatus_ACTIVATING
3410 }
3411 }
3412 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3413 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3414 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3415 operState = voltha.OperStatus_DISCOVERED
3416 }
3417
3418 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
3419 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3420 logger.Errorw(ctx, "unable to update device state to core",
3421 log.Fields{"OperState": onuDevEntry.sOnuPersistentData.PersOperState, "Err": err})
3422 }
3423 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003424 logger.Debugw(ctx, "reconciling has been finished in time",
3425 log.Fields{"device-id": dh.deviceID})
3426 } else {
Maninderb5187552021-03-23 22:23:42 +05303427 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003428 log.Fields{"device-id": dh.deviceID})
3429 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003430 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Maninderb5187552021-03-23 22:23:42 +05303431 //TODO: handle notification to core if reconciling timed out
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003432 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3433 log.Fields{"device-id": dh.deviceID})
3434 }
3435 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003436 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003437 dh.mutexReconcilingFlag.Unlock()
3438 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003439 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003440 dh.mutexReconcilingFlag.Lock()
3441 if skipOnuConfig {
3442 dh.reconciling = cSkipOnuConfigReconciling
3443 } else {
3444 dh.reconciling = cOnuConfigReconciling
3445 }
3446 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003447}
3448
3449func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3450 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3451 if dh.isReconciling() {
3452 dh.chReconcilingFinished <- true
3453 } else {
3454 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3455 }
3456}
3457
3458func (dh *deviceHandler) isReconciling() bool {
3459 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003460 defer dh.mutexReconcilingFlag.RUnlock()
3461 return dh.reconciling != cNoReconciling
3462}
3463
3464func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3465 dh.mutexReconcilingFlag.RLock()
3466 defer dh.mutexReconcilingFlag.RUnlock()
3467 return dh.reconciling == cSkipOnuConfigReconciling
3468}
3469
3470func (dh *deviceHandler) setDeviceReason(value uint8) {
3471 dh.mutexDeviceReason.Lock()
3472 dh.deviceReason = value
3473 dh.mutexDeviceReason.Unlock()
3474}
3475
3476func (dh *deviceHandler) getDeviceReason() uint8 {
3477 dh.mutexDeviceReason.RLock()
3478 value := dh.deviceReason
3479 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003480 return value
3481}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003482
3483func (dh *deviceHandler) getDeviceReasonString() string {
3484 return deviceReasonMap[dh.getDeviceReason()]
3485}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003486
3487func (dh *deviceHandler) setReconcilingFlows(value bool) {
3488 dh.mutexReconcilingFlowsFlag.Lock()
3489 dh.reconcilingFlows = value
3490 dh.mutexReconcilingFlowsFlag.Unlock()
3491}
3492
3493func (dh *deviceHandler) isReconcilingFlows() bool {
3494 dh.mutexReconcilingFlowsFlag.RLock()
3495 value := dh.reconcilingFlows
3496 dh.mutexReconcilingFlowsFlag.RUnlock()
3497 return value
3498}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003499
3500func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3501 dh.mutexReadyForOmciConfig.Lock()
3502 dh.readyForOmciConfig = flagValue
3503 dh.mutexReadyForOmciConfig.Unlock()
3504}
3505
3506func (dh *deviceHandler) isReadyForOmciConfig() bool {
3507 dh.mutexReadyForOmciConfig.RLock()
3508 flagValue := dh.readyForOmciConfig
3509 dh.mutexReadyForOmciConfig.RUnlock()
3510 return flagValue
3511}