blob: 59cd8d0e01f6425e73252445672620acf0769d59 [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
188 exitChannel chan int
189 lockDevice sync.RWMutex
190 pOnuIndication *oop.OnuIndication
191 deviceReason uint8
192 mutexDeviceReason sync.RWMutex
193 pLockStateFsm *lockStateFsm
194 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000195
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196 //flowMgr *OpenOltFlowMgr
197 //eventMgr *OpenOltEventMgr
198 //resourceMgr *rsrcMgr.OpenOltResourceMgr
199
200 //discOnus sync.Map
201 //onus sync.Map
202 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000203 collectorIsRunning bool
204 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000205 stopCollector chan bool
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530206 alarmManagerIsRunning bool
207 mutextAlarmManagerFlag sync.RWMutex
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530208 stopAlarmManager chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000209 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000210 uniEntityMap map[uint32]*onuUniPort
mpagenkof1fc3862021-02-16 10:09:52 +0000211 mutexKvStoreContext sync.Mutex
212 lockVlanConfig sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000213 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
mpagenko80622a52021-02-09 16:53:23 +0000214 lockUpgradeFsm sync.RWMutex
215 pOnuUpradeFsm *OnuUpgradeFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000216 reconciling uint8
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000217 mutexReconcilingFlag sync.RWMutex
218 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
mpagenkofc4f56e2020-11-04 17:17:49 +0000219 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220}
221
Himani Chawla6d2ae152020-09-02 13:11:20 +0530222//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530223func 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 +0530224 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225 dh.coreProxy = cp
226 dh.AdapterProxy = ap
227 dh.EventProxy = ep
228 cloned := (proto.Clone(device)).(*voltha.Device)
229 dh.deviceID = cloned.Id
230 dh.DeviceType = cloned.Type
231 dh.adminState = "up"
232 dh.device = cloned
233 dh.pOpenOnuAc = adapter
234 dh.exitChannel = make(chan int, 1)
235 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000236 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000237 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530239 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530240 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000241 dh.stopHeartbeatCheck = make(chan bool, 2)
242 //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 +0000243 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530244 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000245 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000246 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000247 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000248 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000249 dh.chReconcilingFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000250 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800252 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
253 dh.pmConfigs = cloned.PmConfigs
254 } /* else {
255 // will be populated when onu_metrics_mananger is initialized.
256 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800257
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 // Device related state machine
259 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000260 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000262 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
263 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
264 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
265 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
266 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267 },
268 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
270 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
271 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
272 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
273 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
274 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
275 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
276 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277 },
278 )
mpagenkoaf801632020-07-03 10:00:42 +0000279
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280 return &dh
281}
282
Himani Chawla6d2ae152020-09-02 13:11:20 +0530283// start save the device to the data model
284func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288}
289
Himani Chawla4d908332020-08-31 12:30:20 +0530290/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530292func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 logger.Debug("stopping-device-handler")
294 dh.exitChannel <- 1
295}
Himani Chawla4d908332020-08-31 12:30:20 +0530296*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297
298// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530299// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300
Girish Gowdrae0140f02021-02-02 16:55:09 -0800301//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530302func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000303 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000306 if dh.pDeviceStateFsm.Is(devStNull) {
307 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800311 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
312 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800313 // Now, set the initial PM configuration for that device
314 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
315 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
316 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800317 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320 }
321
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322}
323
mpagenko057889c2021-01-21 16:51:58 +0000324func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530325 msgBody := msg.GetBody()
326 omciMsg := &ic.InterAdapterOmciMessage{}
327 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530329 "device-id": dh.deviceID, "error": err})
330 return err
331 }
332
mpagenko80622a52021-02-09 16:53:23 +0000333 /* 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 +0530334 //assuming omci message content is hex coded!
335 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530337 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000338 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000341 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000342 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000343 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 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 +0530345 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000347 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530348}
349
Himani Chawla6d2ae152020-09-02 13:11:20 +0530350func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000353
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000355
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000357 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000359 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
360 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 if dh.pOnuTP == nil {
362 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530364 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000367 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000369 "device-state": dh.getDeviceReasonString()})
370 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530371 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000372 //previous state test here was just this one, now extended for more states to reject the SetRequest:
373 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
374 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530375
376 msgBody := msg.GetBody()
377 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
378 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 "device-id": dh.deviceID, "error": err})
381 return err
382 }
383
384 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
386 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389
390 if techProfMsg.UniId > 255 {
391 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
392 techProfMsg.UniId, dh.deviceID))
393 }
394 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800395 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
396 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000397 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800398 return err
399 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400
dbainbri4d3a0dc2020-12-02 00:33:42 +0000401 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530402 // if there has been some change for some uni TechProfilePath
403 //in order to allow concurrent calls to other dh instances we do not wait for execution here
404 //but doing so we can not indicate problems to the caller (who does what with that then?)
405 //by now we just assume straightforward successful execution
406 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
407 // possible problems to the caller later autonomously
408
409 // deadline context to ensure completion of background routines waited for
410 //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 +0530411 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 dctx, cancel := context.WithDeadline(context.Background(), deadline)
413
Girish Gowdra041dcb32020-11-16 16:54:30 -0800414 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 pDevEntry.resetKvProcessingErrorIndication()
416
Himani Chawla26e555c2020-08-31 12:30:20 +0530417 var wg sync.WaitGroup
418 wg.Add(2) // for the 2 go routines to finish
419 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000420 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
421 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
422 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423
Girish Gowdra041dcb32020-11-16 16:54:30 -0800424 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530427 return nil
428}
429
Himani Chawla6d2ae152020-09-02 13:11:20 +0530430func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530432 msg *ic.InterAdapterMessage) error {
433
dbainbri4d3a0dc2020-12-02 00:33:42 +0000434 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000435
dbainbri4d3a0dc2020-12-02 00:33:42 +0000436 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000437 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000438 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000439 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
440 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530441 if dh.pOnuTP == nil {
442 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530444 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 }
447
448 msgBody := msg.GetBody()
449 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
450 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 "device-id": dh.deviceID, "error": err})
453 return err
454 }
455
456 //compare TECH_PROFILE_DOWNLOAD_REQUEST
457 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000458 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530459
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000460 if delGemPortMsg.UniId > 255 {
461 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
462 delGemPortMsg.UniId, dh.deviceID))
463 }
464 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800465 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
466 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000467 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 -0800468 return err
469 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530470
mpagenkofc4f56e2020-11-04 17:17:49 +0000471 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000472
mpagenkofc4f56e2020-11-04 17:17:49 +0000473 // deadline context to ensure completion of background routines waited for
474 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
475 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476
Girish Gowdra041dcb32020-11-16 16:54:30 -0800477 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478
mpagenkofc4f56e2020-11-04 17:17:49 +0000479 var wg sync.WaitGroup
480 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000482 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000484
Girish Gowdra041dcb32020-11-16 16:54:30 -0800485 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530486}
487
Himani Chawla6d2ae152020-09-02 13:11:20 +0530488func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000493
dbainbri4d3a0dc2020-12-02 00:33:42 +0000494 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
498 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530499 if dh.pOnuTP == nil {
500 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000501 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530504 }
505
506 msgBody := msg.GetBody()
507 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
508 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530510 "device-id": dh.deviceID, "error": err})
511 return err
512 }
513
514 //compare TECH_PROFILE_DOWNLOAD_REQUEST
515 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000517
518 if delTcontMsg.UniId > 255 {
519 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
520 delTcontMsg.UniId, dh.deviceID))
521 }
522 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800523 tpPath := delTcontMsg.TpPath
524 tpID, err := GetTpIDFromTpPath(tpPath)
525 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800527 return err
528 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000529
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530532 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530533 dctx, cancel := context.WithDeadline(context.Background(), deadline)
534
Girish Gowdra041dcb32020-11-16 16:54:30 -0800535 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000536 pDevEntry.resetKvProcessingErrorIndication()
537
Himani Chawla26e555c2020-08-31 12:30:20 +0530538 var wg sync.WaitGroup
539 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 cResourceTcont, delTcontMsg.AllocId, &wg)
542 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000543 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
544 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000545
Girish Gowdra041dcb32020-11-16 16:54:30 -0800546 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530547 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530548 return nil
549}
550
Himani Chawla6d2ae152020-09-02 13:11:20 +0530551//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000552// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
553// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000554func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000555 msgID := msg.Header.Id
556 msgType := msg.Header.Type
557 fromTopic := msg.Header.FromTopic
558 toTopic := msg.Header.ToTopic
559 toDeviceID := msg.Header.ToDeviceId
560 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000561 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000562 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
563
564 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000565 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000566 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
567 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000568 {
mpagenko057889c2021-01-21 16:51:58 +0000569 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000570 }
mpagenkoaf801632020-07-03 10:00:42 +0000571 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
572 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000573 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000574 }
575 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
576 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000577 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000578
mpagenkoaf801632020-07-03 10:00:42 +0000579 }
580 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
581 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000582 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000583 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000584 default:
585 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000587 "msgType": msg.Header.Type, "device-id": dh.deviceID})
588 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000589 }
590 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000591}
592
mpagenkodff5dda2020-08-28 11:52:01 +0000593//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000594func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
595 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000596 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000598
mpagenko01e726e2020-10-23 09:45:29 +0000599 var retError error = nil
600 //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 +0000601 if apOfFlowChanges.ToRemove != nil {
602 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000603 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000605 "device-id": dh.deviceID})
606 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000607 continue
608 }
609 flowInPort := flow.GetInPort(flowItem)
610 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611 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 +0000612 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
613 continue
614 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000615 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000616 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000618 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000619 continue
620 } else {
621 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530622 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000623 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
624 loUniPort = uniPort
625 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000627 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
628 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
629 flowInPort, dh.deviceID)
630 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000631 }
632 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000633 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000634 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000635 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000637 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000638 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000640 log.Fields{"device-id": dh.deviceID, "error": err})
641 retError = err
642 continue
643 //return err
644 } else { // if last setting succeeds, overwrite possibly previously set error
645 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000646 }
647 }
648 }
649 }
mpagenko01e726e2020-10-23 09:45:29 +0000650 if apOfFlowChanges.ToAdd != nil {
651 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
652 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000654 "device-id": dh.deviceID})
655 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
656 continue
657 }
658 flowInPort := flow.GetInPort(flowItem)
659 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 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 +0000661 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
662 continue
663 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
664 } else if flowInPort == dh.ponPortNumber {
665 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000667 "device-id": dh.deviceID, "inPort": flowInPort})
668 continue
669 } else {
670 // this is the relevant upstream flow
671 var loUniPort *onuUniPort
672 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
673 loUniPort = uniPort
674 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000676 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
677 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
678 flowInPort, dh.deviceID)
679 continue
680 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
681 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000682 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
683 // if not, we just throw some error here to have an indication about that, if we really need to support that
684 // then we would need to create some means to activate the internal stored flows
685 // after the device gets active automatically (and still with its dependency to the TechProfile)
686 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
687 // also abort for the other still possible flows here
688 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000690 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000691 return fmt.Errorf("improper device state on device %s", dh.deviceID)
692 }
693
mpagenko01e726e2020-10-23 09:45:29 +0000694 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000696 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
697 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000699 //try next flow after processing error
700 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000702 log.Fields{"device-id": dh.deviceID, "error": err})
703 retError = err
704 continue
705 //return err
706 } else { // if last setting succeeds, overwrite possibly previously set error
707 retError = nil
708 }
709 }
710 }
711 }
712 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000713}
714
Himani Chawla6d2ae152020-09-02 13:11:20 +0530715//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000716//following are the expected device states after this activity:
717//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
718// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
720 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000721
mpagenko900ee4b2020-10-12 11:56:34 +0000722 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000723 //note that disableDevice sequences in some 'ONU active' state may yield also
724 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000725 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000726 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000727 //disable-device shall be just a UNi/ONU-G related admin state setting
728 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000729
mpagenkofc4f56e2020-11-04 17:17:49 +0000730 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000731 // disable UNI ports/ONU
732 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
733 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000735 } else { //LockStateFSM already init
736 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000738 }
739 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000741 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000742 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000743 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
744 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000746 }
mpagenko01e726e2020-10-23 09:45:29 +0000747 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000748
749 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000751 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300752 }
753}
754
Himani Chawla6d2ae152020-09-02 13:11:20 +0530755//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
757 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000758
mpagenkofc4f56e2020-11-04 17:17:49 +0000759 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
760 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
761 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
762 // for real ONU's that should have nearly no influence
763 // Note that for real ONU's there is anyway a problematic situation with following sequence:
764 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
765 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
766 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
767 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
768
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000769 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000770 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000771 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000773 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000774 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000776 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300777}
778
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
780 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000781
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000783 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000785 return
786 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000788 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000790 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000792 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000793 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000794 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000795 }
Himani Chawla4d908332020-08-31 12:30:20 +0530796 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000797 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
798 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
799 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
800 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000802}
803
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
805 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000806
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000810 dh.stopReconciling(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000811 return
812 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000813 dh.pOnuTP.lockTpProcMutex()
814 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000815 pDevEntry.persUniConfigMutex.RLock()
816 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000817
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000818 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000820 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000821 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000822 return
823 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000824 techProfsFound := false
825 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000827 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
828 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000829 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000830 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000831 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000832 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000833 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800834 for tpID := range uniData.PersTpPathMap {
835 // deadline context to ensure completion of background routines waited for
836 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
837 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000839
Girish Gowdra041dcb32020-11-16 16:54:30 -0800840 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
841 var wg sync.WaitGroup
842 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
844 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800845 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800847 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000849 if len(uniData.PersFlowParams) != 0 {
850 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000851 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000853 if !techProfsFound {
854 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
855 log.Fields{"device-id": dh.deviceID})
856 dh.stopReconciling(ctx)
857 return
858 }
859 if dh.isSkipOnuConfigReconciling() {
860 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
861 }
862 if !flowsFound {
863 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
864 log.Fields{"device-id": dh.deviceID})
865 dh.stopReconciling(ctx)
866 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000867}
868
dbainbri4d3a0dc2020-12-02 00:33:42 +0000869func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
870 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000873 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000875 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000876 return
877 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000878 pDevEntry.persUniConfigMutex.RLock()
879 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000880
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000881 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000882 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000884 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000885 return
886 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000887 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000888 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000889 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
890 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000891 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000892 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000893 continue
894 }
895 if len(uniData.PersTpPathMap) == 0 {
896 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
897 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000898 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 var uniPort *onuUniPort
900 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000902 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000903 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
904 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
905 dh.stopReconciling(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000906 return
907 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 flowsFound = true
909 flowsProcessed := 0
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000910 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000911 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000912 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000913 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000914 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000915 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000916 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
917 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000919 }
mpagenkof1fc3862021-02-16 10:09:52 +0000920 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000921 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000922 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000924 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000925 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 }
928 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000929 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000930 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
932 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
933 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
934 }
935 if !flowsFound {
936 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
937 log.Fields{"device-id": dh.deviceID})
938 dh.stopReconciling(ctx)
939 return
940 }
941 if dh.isSkipOnuConfigReconciling() {
942 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000943 }
944}
945
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
947 logger.Debugw(ctx, "reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000948
949 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000950 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000951}
952
dbainbri4d3a0dc2020-12-02 00:33:42 +0000953func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
954 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000955
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000957 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000958 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000960 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000961 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000962
963 // deadline context to ensure completion of background routines waited for
964 //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 +0530965 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000967
968 pDevEntry.resetKvProcessingErrorIndication()
969
970 var wg sync.WaitGroup
971 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
973 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000975 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000976 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000977}
978
mpagenko15ff4a52021-03-02 10:09:20 +0000979//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
980// before this change here return like this was used:
981// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
982//was and is called in background - error return does not make sense
983func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
984 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
985 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +0000987 return
ozgecanetsiae11479f2020-07-06 09:44:47 +0300988 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530990 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000991 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +0000992 return
Himani Chawla4d908332020-08-31 12:30:20 +0530993 }
mpagenko01e726e2020-10-23 09:45:29 +0000994
995 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000997
dbainbri4d3a0dc2020-12-02 00:33:42 +0000998 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000999 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001001 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001002 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001003 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001004 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001005 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001007 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001008 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001009 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +00001010 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1011 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1012 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1013 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001014}
1015
mpagenkoc8bba412021-01-15 15:38:44 +00001016//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001017func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1018 apDownloadManager *adapterDownloadManager) error {
1019 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001020 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001021
1022 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001023 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1024 if pDevEntry == nil {
1025 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1026 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1027 }
1028
mpagenko80622a52021-02-09 16:53:23 +00001029 if dh.ReadyForSpecificOmciConfig {
mpagenko15ff4a52021-03-02 10:09:20 +00001030 var inactiveImageID uint16
1031 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1032 dh.lockUpgradeFsm.Lock()
1033 defer dh.lockUpgradeFsm.Unlock()
1034 if dh.pOnuUpradeFsm == nil {
1035 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1036 if err == nil {
1037 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1038 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1039 "device-id": dh.deviceID, "error": err})
1040 }
1041 } else {
1042 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001043 "device-id": dh.deviceID, "error": err})
1044 }
mpagenko15ff4a52021-03-02 10:09:20 +00001045 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1046 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1047 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1048 if pUpgradeStatemachine != nil {
1049 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1050 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1051 "device-id": dh.deviceID, "error": err})
1052 }
1053 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1054 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1055 // for now a second start of download should work again
1056 } else { //should never occur
1057 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1058 "device-id": dh.deviceID})
1059 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001060 }
mpagenko80622a52021-02-09 16:53:23 +00001061 }
mpagenko15ff4a52021-03-02 10:09:20 +00001062 } else {
1063 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1064 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001065 }
1066 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001067 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1068 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001069 }
1070 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001071}
1072
Himani Chawla6d2ae152020-09-02 13:11:20 +05301073// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074// #####################################################################################
1075
1076// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301077// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001078
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1080 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 +00001081}
1082
1083// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001084func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001085
dbainbri4d3a0dc2020-12-02 00:33:42 +00001086 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001087 var err error
1088
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001089 // populate what we know. rest comes later after mib sync
1090 dh.device.Root = false
1091 dh.device.Vendor = "OpenONU"
1092 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001093 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001094 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001095
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001096 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001097
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001098 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1100 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301101 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001102 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001104 log.Fields{"device-id": dh.deviceID})
1105 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001106
Himani Chawla4d908332020-08-31 12:30:20 +05301107 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001108 dh.ponPortNumber = dh.device.ParentPortNo
1109
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001110 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1111 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1112 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301115 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116
1117 /*
1118 self._pon = PonPort.create(self, self._pon_port_number)
1119 self._pon.add_peer(self.parent_id, self._pon_port_number)
1120 self.logger.debug('adding-pon-port-to-agent',
1121 type=self._pon.get_port().type,
1122 admin_state=self._pon.get_port().admin_state,
1123 oper_status=self._pon.get_port().oper_status,
1124 )
1125 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001126 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001127 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001128 var ponPortNo uint32 = 1
1129 if dh.ponPortNumber != 0 {
1130 ponPortNo = dh.ponPortNumber
1131 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001133 pPonPort := &voltha.Port{
1134 PortNo: ponPortNo,
1135 Label: fmt.Sprintf("pon-%d", ponPortNo),
1136 Type: voltha.Port_PON_ONU,
1137 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301138 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001139 PortNo: ponPortNo}}, // Peer port is parent's port number
1140 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1142 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001143 e.Cancel(err)
1144 return
1145 }
1146 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001148 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001150}
1151
1152// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001154
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001156 var err error
1157 /*
1158 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1159 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1160 return nil
1161 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1163 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001164 e.Cancel(err)
1165 return
1166 }
1167
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001168 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001170 // reconcilement will be continued after mib download is done
1171 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001172
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001173 /*
1174 ############################################################################
1175 # Setup Alarm handler
1176 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1177 device.serial_number)
1178 ############################################################################
1179 # Setup PM configuration for this device
1180 # Pass in ONU specific options
1181 kwargs = {
1182 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1183 'heartbeat': self.heartbeat,
1184 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1185 }
1186 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1187 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1188 self.logical_device_id, device.serial_number,
1189 grouped=True, freq_override=False, **kwargs)
1190 pm_config = self._pm_metrics.make_proto()
1191 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1192 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1193 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1194
1195 # Note, ONU ID and UNI intf set in add_uni_port method
1196 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1197 ani_ports=[self._pon])
1198
1199 # Code to Run OMCI Test Action
1200 kwargs_omci_test_action = {
1201 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1202 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1203 }
1204 serial_number = device.serial_number
1205 self._test_request = OmciTestRequest(self.core_proxy,
1206 self.omci_agent, self.device_id,
1207 AniG, serial_number,
1208 self.logical_device_id,
1209 exclusive=False,
1210 **kwargs_omci_test_action)
1211
1212 self.enabled = True
1213 else:
1214 self.logger.info('onu-already-activated')
1215 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001216
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001218}
1219
1220// doStateConnected get the device info and update to voltha core
1221// for comparison of the original method (not that easy to uncomment): compare here:
1222// voltha-openolt-adapter/adaptercore/device_handler.go
1223// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001224func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001225
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301227 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001228 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001230}
1231
1232// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001233func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001234
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301236 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001237 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001239
1240 /*
1241 // Synchronous call to update device state - this method is run in its own go routine
1242 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1243 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001244 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 +00001245 return err
1246 }
1247 return nil
1248 */
1249}
1250
1251// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001253
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001255 var err error
1256
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001257 device := dh.device
1258 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001259 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001261 e.Cancel(err)
1262 return
1263 }
1264
1265 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267 /*
1268 // Update the all ports state on that device to disable
1269 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001270 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001271 return er
1272 }
1273
1274 //Update the device oper state and connection status
1275 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1276 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1277 dh.device = cloned
1278
1279 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001280 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001281 return er
1282 }
1283
1284 //get the child device for the parent device
1285 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1286 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001287 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001288 return err
1289 }
1290 for _, onuDevice := range onuDevices.Items {
1291
1292 // Update onu state as down in onu adapter
1293 onuInd := oop.OnuIndication{}
1294 onuInd.OperState = "down"
1295 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1296 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1297 if er != nil {
1298 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001299 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001300 //Do not return here and continue to process other ONUs
1301 }
1302 }
1303 // * Discovered ONUs entries need to be cleared , since after OLT
1304 // is up, it starts sending discovery indications again* /
1305 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001306 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001307 return nil
1308 */
Himani Chawla4d908332020-08-31 12:30:20 +05301309 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001310 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001311 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001312}
1313
Himani Chawla6d2ae152020-09-02 13:11:20 +05301314// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001315// #################################################################################
1316
1317// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301318// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001319
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001320//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001321func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001322 dh.lockDevice.RLock()
1323 pOnuDeviceEntry := dh.pOnuOmciDevice
1324 if aWait && pOnuDeviceEntry == nil {
1325 //keep the read sema short to allow for subsequent write
1326 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001327 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001328 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1329 // so it might be needed to wait here for that event with some timeout
1330 select {
1331 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001332 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001333 return nil
1334 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001335 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001336 // if written now, we can return the written value without sema
1337 return dh.pOnuOmciDevice
1338 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001339 }
mpagenko3af1f032020-06-10 08:53:41 +00001340 dh.lockDevice.RUnlock()
1341 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342}
1343
Himani Chawla6d2ae152020-09-02 13:11:20 +05301344//setOnuDeviceEntry sets the ONU device entry within the handler
1345func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301346 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001347 dh.lockDevice.Lock()
1348 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001349 dh.pOnuOmciDevice = apDeviceEntry
1350 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001351 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301352 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001353}
1354
Himani Chawla6d2ae152020-09-02 13:11:20 +05301355//addOnuDeviceEntry creates a new ONU device or returns the existing
1356func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001357 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001358
dbainbri4d3a0dc2020-12-02 00:33:42 +00001359 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001360 if deviceEntry == nil {
1361 /* costum_me_map in python code seems always to be None,
1362 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1363 /* also no 'clock' argument - usage open ...*/
1364 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001365 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001366 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001367 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301368 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001369 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301370 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001371 // fire deviceEntry ready event to spread to possibly waiting processing
1372 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001373 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001374 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001375 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001376 }
1377 // might be updated with some error handling !!!
1378 return nil
1379}
1380
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1382 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001383 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1384
1385 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001386
dbainbri4d3a0dc2020-12-02 00:33:42 +00001387 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001388 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001389 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001390 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1391 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001392 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 if err := dh.storePersistentData(ctx); err != nil {
1394 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001395 log.Fields{"device-id": dh.deviceID, "err": err})
1396 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001398 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001400 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1401 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001402 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001403 }
1404 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001405 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001406 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001407
1408 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001409 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 +00001410 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001411 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001412 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001413 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001414 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1415 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1416 // 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 +00001417 // 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 +00001418 // so let's just try to keep it simple ...
1419 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001421 if err != nil || device == nil {
1422 //TODO: needs to handle error scenarios
1423 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1424 return errors.New("Voltha Device not found")
1425 }
1426 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001427
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001429 return err
mpagenko3af1f032020-06-10 08:53:41 +00001430 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001431
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001432 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001433
1434 /* this might be a good time for Omci Verify message? */
1435 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001437 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001438 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440
1441 /* give the handler some time here to wait for the OMCi verification result
1442 after Timeout start and try MibUpload FSM anyway
1443 (to prevent stopping on just not supported OMCI verification from ONU) */
1444 select {
1445 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001447 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001449 }
1450
1451 /* In py code it looks earlier (on activate ..)
1452 # Code to Run OMCI Test Action
1453 kwargs_omci_test_action = {
1454 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1455 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1456 }
1457 serial_number = device.serial_number
1458 self._test_request = OmciTestRequest(self.core_proxy,
1459 self.omci_agent, self.device_id,
1460 AniG, serial_number,
1461 self.logical_device_id,
1462 exclusive=False,
1463 **kwargs_omci_test_action)
1464 ...
1465 # Start test requests after a brief pause
1466 if not self._test_request_started:
1467 self._test_request_started = True
1468 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1469 reactor.callLater(tststart, self._test_request.start_collector)
1470
1471 */
1472 /* which is then: in omci_test_request.py : */
1473 /*
1474 def start_collector(self, callback=None):
1475 """
1476 Start the collection loop for an adapter if the frequency > 0
1477
1478 :param callback: (callable) Function to call to collect PM data
1479 """
1480 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1481 if callback is None:
1482 callback = self.perform_test_omci
1483
1484 if self.lc is None:
1485 self.lc = LoopingCall(callback)
1486
1487 if self.default_freq > 0:
1488 self.lc.start(interval=self.default_freq / 10)
1489
1490 def perform_test_omci(self):
1491 """
1492 Perform the initial test request
1493 """
1494 ani_g_entities = self._device.configuration.ani_g_entities
1495 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1496 is not None else None
1497 self._entity_id = ani_g_entities_ids[0]
1498 self.logger.info('perform-test', entity_class=self._entity_class,
1499 entity_id=self._entity_id)
1500 try:
1501 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1502 result = yield self._device.omci_cc.send(frame)
1503 if not result.fields['omci_message'].fields['success_code']:
1504 self.logger.info('Self-Test Submitted Successfully',
1505 code=result.fields[
1506 'omci_message'].fields['success_code'])
1507 else:
1508 raise TestFailure('Test Failure: {}'.format(
1509 result.fields['omci_message'].fields['success_code']))
1510 except TimeoutError as e:
1511 self.deferred.errback(failure.Failure(e))
1512
1513 except Exception as e:
1514 self.logger.exception('perform-test-Error', e=e,
1515 class_id=self._entity_class,
1516 entity_id=self._entity_id)
1517 self.deferred.errback(failure.Failure(e))
1518
1519 */
1520
1521 // PM related heartbeat??? !!!TODO....
1522 //self._heartbeat.enabled = True
1523
mpagenko1cc3cb42020-07-27 15:24:38 +00001524 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1525 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1526 * 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 +05301527 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001528 */
1529 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001530 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001531 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001532 if pMibUlFsm.Is(ulStDisabled) {
1533 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534 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 +00001535 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301536 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301538 //Determine ONU status and start/re-start MIB Synchronization tasks
1539 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001540 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301541 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 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 +00001543 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544 }
Himani Chawla4d908332020-08-31 12:30:20 +05301545 } else {
1546 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547 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 +00001548 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301549 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001551 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001552 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001554 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001555 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001556 }
1557 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001559 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001560 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001561
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001562 if !dh.getCollectorIsRunning() {
1563 // Start PM collector routine
1564 go dh.startCollector(ctx)
1565 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301566 if !dh.getAlarmManagerIsRunning() {
1567 go dh.startAlarmManager(ctx)
1568 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301569
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570 return nil
1571}
1572
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001574 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001575 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001576 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001578
mpagenko900ee4b2020-10-12 11:56:34 +00001579 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1580 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1581 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001582 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001584 log.Fields{"device-id": dh.deviceID, "error": err})
1585 // abort: system behavior is just unstable ...
1586 return err
1587 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001588 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001589 _ = 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 +00001590
1591 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1592 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1593 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001595 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001597 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001598 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001600
1601 //TODO!!! remove existing traffic profiles
1602 /* from py code, if TP's exist, remove them - not yet implemented
1603 self._tp = dict()
1604 # Let TP download happen again
1605 for uni_id in self._tp_service_specific_task:
1606 self._tp_service_specific_task[uni_id].clear()
1607 for uni_id in self._tech_profile_download_done:
1608 self._tech_profile_download_done[uni_id].clear()
1609 */
1610
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001612
mpagenkofc4f56e2020-11-04 17:17:49 +00001613 dh.ReadyForSpecificOmciConfig = false
1614
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001616 // abort: system behavior is just unstable ...
1617 return err
1618 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001620 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001622 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001623 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001625 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001626 // abort: system behavior is just unstable ...
1627 return err
1628 }
1629 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001631 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001632 return nil
1633}
1634
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001635func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001636 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1637 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1638 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1639 // and using the stop/reset event should never harm
1640
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001642 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001644 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1645 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001646 if includingMibSyncFsm {
1647 //the MibSync FSM might be active all the ONU-active time,
1648 // hence it must be stopped unconditionally
1649 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1650 if pMibUlFsm != nil {
1651 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1652 }
mpagenko900ee4b2020-10-12 11:56:34 +00001653 }
1654 //MibDownload may run
1655 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1656 if pMibDlFsm != nil {
1657 _ = pMibDlFsm.Event(dlEvReset)
1658 }
1659 //port lock/unlock FSM's may be active
1660 if dh.pUnlockStateFsm != nil {
1661 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1662 }
1663 if dh.pLockStateFsm != nil {
1664 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1665 }
1666 //techProfile related PonAniConfigFsm FSM may be active
1667 if dh.pOnuTP != nil {
1668 // should always be the case here
1669 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1670 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001671 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1672 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1673 }
mpagenko900ee4b2020-10-12 11:56:34 +00001674 }
1675 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001676 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001677 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001678 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00001679 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001680 //VlanFilterFsm exists and was already started
1681 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1682 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001683 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001684 // no need to remove specific data
1685 pVlanFilterFsm.RequestClearPersistency(false)
1686 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001687 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1688 }
mpagenkof1fc3862021-02-16 10:09:52 +00001689 } else {
1690 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001691 }
1692 }
1693 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001694 if dh.getCollectorIsRunning() {
1695 // Stop collector routine
1696 dh.stopCollector <- true
1697 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301698 if dh.getAlarmManagerIsRunning() {
1699 dh.stopAlarmManager <- true
1700 }
1701
mpagenko80622a52021-02-09 16:53:23 +00001702 //reset a possibly running upgrade FSM
1703 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1704 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1705 dh.lockUpgradeFsm.RLock()
1706 if dh.pOnuUpradeFsm != nil {
1707 _ = dh.pOnuUpradeFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
1708 }
1709 dh.lockUpgradeFsm.RUnlock()
1710
mpagenko900ee4b2020-10-12 11:56:34 +00001711 return nil
1712}
1713
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1715 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 +05301716
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001717 // store persistent data collected during MIB upload processing
1718 if err := dh.storePersistentData(ctx); err != nil {
1719 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1720 log.Fields{"device-id": dh.deviceID, "err": err})
1721 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001722 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001723 dh.addAllUniPorts(ctx)
1724
mpagenkoa40e99a2020-11-17 13:50:39 +00001725 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1726 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1727 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1728 * disable/enable toggling here to allow traffic
1729 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1730 * like the py comment says:
1731 * # start by locking all the unis till mib sync and initial mib is downloaded
1732 * # this way we can capture the port down/up events when we are ready
1733 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301734
mpagenkoa40e99a2020-11-17 13:50:39 +00001735 // Init Uni Ports to Admin locked state
1736 // *** should generate UniLockStateDone event *****
1737 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001739 } else { //LockStateFSM already init
1740 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001742 }
1743}
1744
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1746 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301747 /* Mib download procedure -
1748 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1749 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001751 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001752 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001753 return
1754 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301755 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1756 if pMibDlFsm != nil {
1757 if pMibDlFsm.Is(dlStDisabled) {
1758 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 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 +05301760 // maybe try a FSM reset and then again ... - TODO!!!
1761 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301763 // maybe use more specific states here for the specific download steps ...
1764 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301766 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301768 //Begin MIB data download (running autonomously)
1769 }
1770 }
1771 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001773 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301774 // maybe try a FSM reset and then again ... - TODO!!!
1775 }
1776 /***** Mib download started */
1777 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301779 }
1780}
1781
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1783 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301784 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001785 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001787 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001788 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1789 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1790 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1791 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301793 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1794 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301796 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301798 }
1799 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301801 log.Fields{"device-id": dh.deviceID})
1802 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001803 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001804
1805 // Initialize classical L2 PM Interval Counters
1806 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1807 // There is no way we should be landing here, but if we do then
1808 // there is nothing much we can do about this other than log error
1809 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1810 }
1811
mpagenkofc4f56e2020-11-04 17:17:49 +00001812 dh.ReadyForSpecificOmciConfig = true
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001813
1814 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1815 if pDevEntry == nil {
1816 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1817 return
1818 }
1819 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
1820 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1821 log.Fields{"device-id": dh.deviceID})
1822 go dh.reconcileDeviceTechProf(ctx)
1823 // reconcilement will be continued after ani config is done
1824 } else {
1825 // *** should generate UniUnlockStateDone event *****
1826 if dh.pUnlockStateFsm == nil {
1827 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1828 } else { //UnlockStateFSM already init
1829 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1830 dh.runUniLockFsm(ctx, false)
1831 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301832 }
1833}
1834
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1836 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301837
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001838 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301840 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1842 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001843 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001845 return
1846 }
1847 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 if err := dh.storePersistentData(ctx); err != nil {
1849 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001850 log.Fields{"device-id": dh.deviceID, "err": err})
1851 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301852 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853 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 +05301854 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001855 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001856 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301857 }
1858}
1859
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1861 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001862 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001864 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1865 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001867 }
1868
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001870 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001872
1873 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001875
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001877 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001879 return
1880 }
1881 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 if err := dh.storePersistentData(ctx); err != nil {
1883 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001884 log.Fields{"device-id": dh.deviceID, "err": err})
1885 }
mpagenko900ee4b2020-10-12 11:56:34 +00001886}
1887
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1889 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001890 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001892 voltha.OperStatus_ACTIVE); err != nil {
1893 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001895 }
1896
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001898 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001899 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001901
1902 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001903 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001904
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001906 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001908 return
1909 }
1910 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001911 if err := dh.storePersistentData(ctx); err != nil {
1912 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001913 log.Fields{"device-id": dh.deviceID, "err": err})
1914 }
mpagenko900ee4b2020-10-12 11:56:34 +00001915}
1916
dbainbri4d3a0dc2020-12-02 00:33:42 +00001917func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001918 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001920 // attention: the device reason update is done based on ONU-UNI-Port related activity
1921 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001922 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001923 // 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 +00001924 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301925 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001926 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001928 }
1929 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001931 // attention: the device reason update is done based on ONU-UNI-Port related activity
1932 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001933 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001934 // 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 +00001935 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001936 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001937 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301938}
1939
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1941 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001942 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301943 // attention: the device reason update is done based on ONU-UNI-Port related activity
1944 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301945
mpagenkof1fc3862021-02-16 10:09:52 +00001946 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001947 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001948 // which may be the case from some previous actvity on another UNI Port of the ONU
1949 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001950 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1951 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001953 }
1954 }
1955 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001956 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001957 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001959 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301960 }
mpagenkof1fc3862021-02-16 10:09:52 +00001961
1962 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1963 //events that request KvStore write
1964 if err := dh.storePersistentData(ctx); err != nil {
1965 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1966 log.Fields{"device-id": dh.deviceID, "err": err})
1967 }
1968 } else {
1969 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
1970 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001971 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301972}
1973
Himani Chawla6d2ae152020-09-02 13:11:20 +05301974//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301976 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001977 case MibDatabaseSync:
1978 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001980 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001981 case UniLockStateDone:
1982 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001984 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001985 case MibDownloadDone:
1986 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001988 }
1989 case UniUnlockStateDone:
1990 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001992 }
mpagenko900ee4b2020-10-12 11:56:34 +00001993 case UniEnableStateDone:
1994 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001996 }
1997 case UniDisableStateDone:
1998 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002000 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002001 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002002 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002004 }
mpagenkof1fc3862021-02-16 10:09:52 +00002005 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002006 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002008 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002009 default:
2010 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002012 }
2013 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002014}
2015
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002017 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002018 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302019 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002020 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002022 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302023 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002025 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002027 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002028 //store UniPort with the System-PortNumber key
2029 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002030 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002031 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2033 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002034 } //error logging already within UniPort method
2035 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002037 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002038 }
2039 }
2040}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002041
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002042func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2043 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2044 if pDevEntry == nil {
2045 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2046 return
2047 }
2048 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2049 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2050 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2051 for _, mgmtEntityID := range pptpInstKeys {
2052 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2053 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2054 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2055 i++
2056 }
2057 } else {
2058 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2059 }
2060 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2061 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2062 for _, mgmtEntityID := range veipInstKeys {
2063 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2064 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2065 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2066 i++
2067 }
2068 } else {
2069 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2070 }
2071 if i == 0 {
2072 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2073 }
2074}
2075
mpagenko3af1f032020-06-10 08:53:41 +00002076// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002078 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302079 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002080 // with following remark:
2081 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2082 // # load on the core
2083
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002084 // 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 +00002085
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002086 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002087 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302088 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302090 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002091 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002092 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 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 +00002094 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002095 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002096 }
mpagenko3af1f032020-06-10 08:53:41 +00002097 }
2098 }
2099}
2100
2101// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002103 // compare enableUniPortStateUpdate() above
2104 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2105 for uniNo, uniPort := range dh.uniEntityMap {
2106 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302107 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002108 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302109 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002110 if !dh.isReconciling() {
2111 //maybe also use getter functions on uniPort - perhaps later ...
2112 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2113 } else {
2114 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2115 }
2116
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002117 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002118 }
2119}
2120
2121// ONU_Active/Inactive announcement on system KAFKA bus
2122// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002124 var de voltha.DeviceEvent
2125 eventContext := make(map[string]string)
2126 //Populating event context
2127 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002128 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002129 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302131 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002132 }
2133 oltSerialNumber := parentDevice.SerialNumber
2134
2135 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2136 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2137 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302138 eventContext["olt-serial-number"] = oltSerialNumber
2139 eventContext["device-id"] = aDeviceID
2140 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002142 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002143
2144 /* Populating device event body */
2145 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302146 de.ResourceId = aDeviceID
2147 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002148 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2149 de.Description = fmt.Sprintf("%s Event - %s - %s",
2150 cEventObjectType, cOnuActivatedEvent, "Raised")
2151 } else {
2152 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2153 de.Description = fmt.Sprintf("%s Event - %s - %s",
2154 cEventObjectType, cOnuActivatedEvent, "Cleared")
2155 }
2156 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2158 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302159 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002160 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302162 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002163}
2164
Himani Chawla4d908332020-08-31 12:30:20 +05302165// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002167 chLSFsm := make(chan Message, 2048)
2168 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302169 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002171 sFsmName = "LockStateFSM"
2172 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002174 sFsmName = "UnLockStateFSM"
2175 }
mpagenko3af1f032020-06-10 08:53:41 +00002176
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002178 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002180 return
2181 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002183 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002184 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302185 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002186 dh.pLockStateFsm = pLSFsm
2187 } else {
2188 dh.pUnlockStateFsm = pLSFsm
2189 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002191 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002193 }
2194}
2195
2196// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002198 /* Uni Port lock/unlock procedure -
2199 ***** should run via 'adminDone' state and generate the argument requested event *****
2200 */
2201 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302202 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002203 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2204 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2205 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002206 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302207 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002208 }
2209 } else {
2210 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2211 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2212 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002213 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302214 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002215 }
2216 }
2217 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002218 if pLSStatemachine.Is(uniStDisabled) {
2219 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002220 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002221 // maybe try a FSM reset and then again ... - TODO!!!
2222 } else {
2223 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002225 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002226 }
2227 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002229 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002230 // maybe try a FSM reset and then again ... - TODO!!!
2231 }
2232 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002233 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002234 // maybe try a FSM reset and then again ... - TODO!!!
2235 }
2236}
2237
mpagenko80622a52021-02-09 16:53:23 +00002238// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002239func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002240 //in here lockUpgradeFsm is already locked
2241 chUpgradeFsm := make(chan Message, 2048)
2242 var sFsmName = "OnuSwUpgradeFSM"
2243 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002244 if apDevEntry.PDevOmciCC == nil {
2245 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2246 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002247 }
mpagenko15ff4a52021-03-02 10:09:20 +00002248 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002249 sFsmName, chUpgradeFsm)
2250 if dh.pOnuUpradeFsm != nil {
2251 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2252 if pUpgradeStatemachine != nil {
2253 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2254 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2255 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2256 // maybe try a FSM reset and then again ... - TODO!!!
2257 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2258 }
2259 /***** LockStateFSM started */
2260 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2261 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2262 } else {
2263 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2264 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2265 // maybe try a FSM reset and then again ... - TODO!!!
2266 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2267 }
2268 } else {
2269 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2270 // maybe try a FSM reset and then again ... - TODO!!!
2271 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2272 }
2273 } else {
2274 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2275 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2276 }
2277 return nil
2278}
2279
2280// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2281func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2282 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2283 "device-id": dh.deviceID})
2284 dh.lockUpgradeFsm.Lock()
2285 defer dh.lockUpgradeFsm.Unlock()
2286 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2287}
2288
mpagenko15ff4a52021-03-02 10:09:20 +00002289// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2290func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2291 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2292 if pDevEntry == nil {
2293 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2294 return
2295 }
2296
2297 dh.lockUpgradeFsm.RLock()
2298 defer dh.lockUpgradeFsm.RUnlock()
2299 if dh.pOnuUpradeFsm != nil {
2300 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2301 if pUpgradeStatemachine != nil {
2302 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2303 // (some manual forced commit could do without)
2304 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
2305 forcedTest := true //TODO!!: needed as long as BBSIM does not fully support SW upgrade simulation
2306 if forcedTest || pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
2307 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2308 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2309 return
2310 }
2311 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2312 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2313 } else {
2314 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2315 log.Fields{"device-id": dh.deviceID})
2316 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2317 return
2318 }
2319 }
2320 }
2321 } else {
2322 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2323 }
2324}
2325
Himani Chawla6d2ae152020-09-02 13:11:20 +05302326//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002328
2329 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002330 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002331 kvbackend := &db.Backend{
2332 Client: dh.pOpenOnuAc.kvClient,
2333 StoreType: dh.pOpenOnuAc.KVStoreType,
2334 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002335 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002336 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2337 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002338
mpagenkoaf801632020-07-03 10:00:42 +00002339 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002340}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302342 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002343
mpagenkodff5dda2020-08-28 11:52:01 +00002344 for _, field := range flow.GetOfbFields(apFlowItem) {
2345 switch field.Type {
2346 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2347 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002349 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2350 }
mpagenko01e726e2020-10-23 09:45:29 +00002351 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002352 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2353 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302354 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002355 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302356 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2357 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002358 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2359 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002360 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2361 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302362 return
mpagenkodff5dda2020-08-28 11:52:01 +00002363 }
2364 }
mpagenko01e726e2020-10-23 09:45:29 +00002365 */
mpagenkodff5dda2020-08-28 11:52:01 +00002366 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2367 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302368 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002369 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302370 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002371 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302372 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002373 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302375 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002376 }
2377 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2378 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002381 "PCP": loAddPcp})
2382 }
2383 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2384 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002385 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002386 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2387 }
2388 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2389 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002391 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2392 }
2393 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2394 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002396 "IPv4-DST": field.GetIpv4Dst()})
2397 }
2398 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2399 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002401 "IPv4-SRC": field.GetIpv4Src()})
2402 }
2403 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2404 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002406 "Metadata": field.GetTableMetadata()})
2407 }
2408 /*
2409 default:
2410 {
2411 //all other entires ignored
2412 }
2413 */
2414 }
2415 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302416}
mpagenkodff5dda2020-08-28 11:52:01 +00002417
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002419 for _, action := range flow.GetActions(apFlowItem) {
2420 switch action.Type {
2421 /* not used:
2422 case of.OfpActionType_OFPAT_OUTPUT:
2423 {
mpagenko01e726e2020-10-23 09:45:29 +00002424 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002425 "Output": action.GetOutput()})
2426 }
2427 */
2428 case of.OfpActionType_OFPAT_PUSH_VLAN:
2429 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002431 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2432 }
2433 case of.OfpActionType_OFPAT_SET_FIELD:
2434 {
2435 pActionSetField := action.GetSetField()
2436 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002437 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002438 "OxcmClass": pActionSetField.Field.OxmClass})
2439 }
2440 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302441 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002442 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302443 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002444 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302445 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002446 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302447 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002448 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002450 "Type": pActionSetField.Field.GetOfbField().Type})
2451 }
2452 }
2453 /*
2454 default:
2455 {
2456 //all other entires ignored
2457 }
2458 */
2459 }
2460 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302461}
2462
2463//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302465 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2466 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2467 var loAddPcp, loSetPcp uint8
2468 var loIPProto uint32
2469 /* the TechProfileId is part of the flow Metadata - compare also comment within
2470 * OLT-Adapter:openolt_flowmgr.go
2471 * Metadata 8 bytes:
2472 * Most Significant 2 Bytes = Inner VLAN
2473 * Next 2 Bytes = Tech Profile ID(TPID)
2474 * Least Significant 4 Bytes = Port ID
2475 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2476 * subscriber related flows.
2477 */
2478
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302480 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302482 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002483 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302484 }
mpagenko551a4d42020-12-08 18:09:20 +00002485 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002486 loCookie := apFlowItem.GetCookie()
2487 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002489 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302490
dbainbri4d3a0dc2020-12-02 00:33:42 +00002491 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002492 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302493 if loIPProto == 2 {
2494 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2495 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002496 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2497 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302498 return nil
2499 }
mpagenko01e726e2020-10-23 09:45:29 +00002500 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002502
2503 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002504 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002505 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2506 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2507 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2508 //TODO!!: Use DeviceId within the error response to rwCore
2509 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002510 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002511 }
2512 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002513 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002514 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2515 } else {
2516 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2517 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2518 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302519 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002520 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002521 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002522 }
mpagenko9a304ea2020-12-16 15:54:01 +00002523
2524 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002525 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002526 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302527 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002528 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002529 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002530 dh.lockVlanConfig.RUnlock()
2531 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002532 }
mpagenkof1fc3862021-02-16 10:09:52 +00002533 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002535 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002536}
2537
2538//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002540 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2541 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2542 //no extra check is done on the rule parameters
2543 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2544 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2545 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2546 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002547 // - 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 +00002548 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002550
2551 /* TT related temporary workaround - should not be needed anymore
2552 for _, field := range flow.GetOfbFields(apFlowItem) {
2553 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2554 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002555 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002556 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2557 if loIPProto == 2 {
2558 // 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 +00002559 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002560 log.Fields{"device-id": dh.deviceID})
2561 return nil
2562 }
2563 }
2564 } //for all OfbFields
2565 */
2566
mpagenko9a304ea2020-12-16 15:54:01 +00002567 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002568 dh.lockVlanConfig.RLock()
2569 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002570 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002572 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002574 log.Fields{"device-id": dh.deviceID})
2575 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002576 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002577 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002578
mpagenko01e726e2020-10-23 09:45:29 +00002579 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002580}
2581
Himani Chawla26e555c2020-08-31 12:30:20 +05302582// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002583// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002584func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002585 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002586 chVlanFilterFsm := make(chan Message, 2048)
2587
dbainbri4d3a0dc2020-12-02 00:33:42 +00002588 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002589 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302591 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002592 }
2593
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002595 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2596 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002597 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002598 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302599 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002600 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002601 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2602 if pVlanFilterStatemachine != nil {
2603 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2604 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302606 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002607 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302608 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302610 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2611 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002612 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002614 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302615 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002616 }
2617 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002618 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002619 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302620 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002621 }
2622 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002624 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302625 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002626 }
2627 return nil
2628}
2629
mpagenkofc4f56e2020-11-04 17:17:49 +00002630//VerifyVlanConfigRequest checks on existence of a given uniPort
2631// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002632func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002633 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2634 var pCurrentUniPort *onuUniPort
2635 for _, uniPort := range dh.uniEntityMap {
2636 // only if this port is validated for operState transfer
2637 if uniPort.uniID == uint8(aUniID) {
2638 pCurrentUniPort = uniPort
2639 break //found - end search loop
2640 }
2641 }
2642 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002644 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2645 return
2646 }
mpagenko551a4d42020-12-08 18:09:20 +00002647 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002648}
2649
mpagenkodff5dda2020-08-28 11:52:01 +00002650//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002651func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002652 //TODO!! verify and start pending flow configuration
2653 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2654 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002655
2656 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302657 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002658 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002659 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2660 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2661 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002662 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2663 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2664 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2665 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2666 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2667 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2668 } else {
2669 /***** UniVlanConfigFsm continued */
2670 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2671 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2672 "UniPort": apUniPort.portNo})
2673 }
2674 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2675 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2676 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2677 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2678 } else {
2679 /***** UniVlanConfigFsm continued */
2680 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2681 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2682 "UniPort": apUniPort.portNo})
2683 }
mpagenkodff5dda2020-08-28 11:52:01 +00002684 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002685 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2686 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002687 "UniPort": apUniPort.portNo})
2688 }
2689 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002690 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2691 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2692 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002693 }
2694 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002695 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002696 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002697 }
mpagenkof1fc3862021-02-16 10:09:52 +00002698 } else {
2699 dh.lockVlanConfig.RUnlock()
2700 }
mpagenkodff5dda2020-08-28 11:52:01 +00002701}
2702
2703//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2704// 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 +00002705func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2706 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002707 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2708 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002709 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302710 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002711 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002712}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002713
Girish Gowdra26a40922021-01-29 17:14:34 -08002714//ProcessPendingTpDelete processes any pending TP delete (if available)
2715func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2716 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2717 if apUniPort == nil {
2718 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2719 return
2720 }
2721 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2722 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2723 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2724 if pAniConfigStatemachine != nil {
2725 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2726 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2727 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2728 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2729 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2730 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2731 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2732 return
2733 }
2734 } else {
2735 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2736 return
2737 }
2738 }
2739 return
2740 }
2741}
2742
mpagenkof1fc3862021-02-16 10:09:52 +00002743//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2744func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2745 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2746 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2747 // obviously then parallel processing on the cancel must be avoided
2748 // deadline context to ensure completion of background routines waited for
2749 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2750 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2751 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2752
2753 aPDevEntry.resetKvProcessingErrorIndication()
2754 var wg sync.WaitGroup
2755 wg.Add(1) // for the 1 go routine to finish
2756
2757 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2758 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2759
2760 return aPDevEntry.getKvProcessingErrorIndication()
2761}
2762
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002763//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2764//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002765func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2766 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002767
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002768 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002769 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002770 return nil
2771 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002772 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002773
dbainbri4d3a0dc2020-12-02 00:33:42 +00002774 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002775 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002776 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002777 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2778 }
2779 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2780
mpagenkof1fc3862021-02-16 10:09:52 +00002781 if aWriteToKvStore {
2782 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2783 }
2784 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002785}
2786
dbainbri4d3a0dc2020-12-02 00:33:42 +00002787func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002788 defer cancel() //ensure termination of context (may be pro forma)
2789 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002790 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002791 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002792}
2793
dbainbri4d3a0dc2020-12-02 00:33:42 +00002794func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002795
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002796 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002797 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002798 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002799 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2800 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002801 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002802 return err
2803 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002805 return nil
2806 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002808 return nil
2809}
2810
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2812 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002813 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002814 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002815 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2816 }
mpagenkof1fc3862021-02-16 10:09:52 +00002817 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002818}
2819
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002820func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2821 var errStr string = ""
2822 for _, err := range errS {
2823 if err != nil {
2824 errStr = errStr + err.Error() + " "
2825 }
2826 }
2827 if errStr != "" {
2828 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2829 }
2830 return nil
2831}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002832
2833// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2834func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2835 dh.lockDevice.RLock()
2836 defer dh.lockDevice.RUnlock()
2837 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2838 return uniPort.entityID, nil
2839 }
2840 return 0, errors.New("error-fetching-uni-port")
2841}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002842
2843// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002844func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2845 var errorsList []error
2846 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 -08002847
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002848 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2849 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2850 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2851
2852 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2853 // successfully.
2854 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2855 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2856 if len(errorsList) > 0 {
2857 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2858 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002859 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002860 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2861 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002862}
2863
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002864func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2865 var err error
2866 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002867 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002868
2869 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2870 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2871 errorsList = append(errorsList, err)
2872 }
2873 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002874 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002875
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002876 return errorsList
2877}
2878
2879func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2880 var err error
2881 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002882 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002883 // Check if group metric related config is updated
2884 for _, v := range pmConfigs.Groups {
2885 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2886 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2887 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2888
2889 if ok && m.frequency != v.GroupFreq {
2890 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2891 errorsList = append(errorsList, err)
2892 }
2893 }
2894 if ok && m.enabled != v.Enabled {
2895 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2896 errorsList = append(errorsList, err)
2897 }
2898 }
2899 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002900 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002901 return errorsList
2902}
2903
2904func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2905 var err error
2906 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002907 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002908 // Check if standalone metric related config is updated
2909 for _, v := range pmConfigs.Metrics {
2910 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002911 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002912 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2913
2914 if ok && m.frequency != v.SampleFreq {
2915 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2916 errorsList = append(errorsList, err)
2917 }
2918 }
2919 if ok && m.enabled != v.Enabled {
2920 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2921 errorsList = append(errorsList, err)
2922 }
2923 }
2924 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002925 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002926 return errorsList
2927}
2928
2929// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002930func (dh *deviceHandler) startCollector(ctx context.Context) {
2931 logger.Debugf(ctx, "startingCollector")
2932
2933 // Start routine to process OMCI GET Responses
2934 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002935 // Initialize the next metric collection time.
2936 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2937 // reset like onu rebooted.
2938 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002939 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002940 for {
2941 select {
2942 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002943 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002944 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002945 // Stop the L2 PM FSM
2946 go func() {
2947 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2948 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2949 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2950 }
2951 } else {
2952 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2953 }
2954 }()
2955
Girish Gowdrae09a6202021-01-12 18:10:59 -08002956 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002957 dh.pOnuMetricsMgr.stopTicks <- true
2958
Girish Gowdrae09a6202021-01-12 18:10:59 -08002959 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002960 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2961 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2962 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2963 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2964 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002965 // Update the next metric collection time.
2966 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002967 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002968 } else {
2969 if dh.pmConfigs.Grouped { // metrics are managed as a group
2970 // parse through the group and standalone metrics to see it is time to collect their metrics
2971 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002972
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002973 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2974 // 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 -08002975 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2976 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002977 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2978 }
2979 }
2980 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2981 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2982 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2983 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2984 }
2985 }
2986 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2987
2988 // parse through the group and update the next metric collection time
2989 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2990 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2991 // 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 -08002992 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2993 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002994 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2995 }
2996 }
2997 // parse through the standalone metrics and update the next metric collection time
2998 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2999 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3000 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3001 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3002 }
3003 }
3004 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3005 } /* else { // metrics are not managed as a group
3006 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3007 } */
3008 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003009 }
3010 }
3011}
kesavandfdf77632021-01-26 23:40:33 -05003012
3013func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3014
3015 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3016 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3017}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003018
mpagenkof1fc3862021-02-16 10:09:52 +00003019func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3020 if pFsm == nil {
3021 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003022 }
mpagenkof1fc3862021-02-16 10:09:52 +00003023 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003024}
3025
mpagenkof1fc3862021-02-16 10:09:52 +00003026func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3027 var pFsm *fsm.FSM
3028 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3029 switch omciFsm {
3030 case cUploadFsm:
3031 {
3032 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3033 }
3034 case cDownloadFsm:
3035 {
3036 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3037 }
3038 case cUniLockFsm:
3039 {
3040 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3041 }
3042 case cUniUnLockFsm:
3043 {
3044 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3045 }
3046 case cL2PmFsm:
3047 {
3048 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3049 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3050 } else {
3051 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003052 }
3053 }
mpagenko80622a52021-02-09 16:53:23 +00003054 case cOnuUpgradeFsm:
3055 {
3056 dh.lockUpgradeFsm.RLock()
3057 defer dh.lockUpgradeFsm.RUnlock()
3058 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3059 }
mpagenkof1fc3862021-02-16 10:09:52 +00003060 default:
3061 {
3062 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3063 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3064 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003065 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003066 }
mpagenkof1fc3862021-02-16 10:09:52 +00003067 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003068}
3069
mpagenkof1fc3862021-02-16 10:09:52 +00003070func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3071 for _, v := range dh.pOnuTP.pAniConfigFsm {
3072 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003073 return false
3074 }
3075 }
3076 return true
3077}
3078
mpagenkof1fc3862021-02-16 10:09:52 +00003079func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3080 dh.lockVlanConfig.RLock()
3081 defer dh.lockVlanConfig.RUnlock()
3082 for _, v := range dh.UniVlanConfigFsmMap {
3083 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3084 return false
3085 }
3086 }
3087 return true //FSM not active - so there is no activity on omci
3088}
3089
3090func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3091 dh.lockVlanConfig.RLock()
3092 defer dh.lockVlanConfig.RUnlock()
3093 for _, v := range dh.UniVlanConfigFsmMap {
3094 if v.pAdaptFsm.pFsm != nil {
3095 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3096 return true //there is at least one VLAN FSM with some active configuration
3097 }
3098 }
3099 }
3100 return false //there is no VLAN FSM with some active configuration
3101}
3102
3103func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3104 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3105 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3106 return false
3107 }
3108 }
3109 // a further check is done to identify, if at least some data traffic related configuration exists
3110 // 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])
3111 return dh.checkUserServiceExists(ctx)
3112}
3113
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003114func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3115 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3116 if err := dh.resetFsms(ctx, false); err != nil {
3117 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3118 // TODO: fatal error reset ONU, delete deviceHandler!
3119 return
3120 }
3121 if !dh.getCollectorIsRunning() {
3122 // Start PM collector routine
3123 go dh.startCollector(ctx)
3124 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303125 if !dh.getAlarmManagerIsRunning() {
3126 go dh.startAlarmManager(ctx)
3127 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003128 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003129 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003130}
3131
3132func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3133 dh.mutexCollectorFlag.Lock()
3134 dh.collectorIsRunning = flagValue
3135 dh.mutexCollectorFlag.Unlock()
3136}
3137
3138func (dh *deviceHandler) getCollectorIsRunning() bool {
3139 dh.mutexCollectorFlag.RLock()
3140 flagValue := dh.collectorIsRunning
3141 dh.mutexCollectorFlag.RUnlock()
3142 return flagValue
3143}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303144
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303145func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3146 dh.mutextAlarmManagerFlag.Lock()
3147 dh.alarmManagerIsRunning = flagValue
3148 dh.mutextAlarmManagerFlag.Unlock()
3149}
3150
3151func (dh *deviceHandler) getAlarmManagerIsRunning() bool {
3152 dh.mutextAlarmManagerFlag.RLock()
3153 flagValue := dh.alarmManagerIsRunning
3154 dh.mutextAlarmManagerFlag.RUnlock()
3155 return flagValue
3156}
3157
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303158func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3159 logger.Debugf(ctx, "startingAlarmManager")
3160
3161 // Start routine to process OMCI GET Responses
3162 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303163 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303164 if stop := <-dh.stopAlarmManager; stop {
3165 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303166 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303167 go func() {
3168 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3169 }()
3170 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3171 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303172
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303173 }
3174}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003175
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003176func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
3177 logger.Debugw(ctx, "start reconciling", log.Fields{"withOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
3178
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003179 if !dh.isReconciling() {
3180 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003181 logger.Debugw(ctx, "wait for channel signal or timeout",
3182 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003183 select {
3184 case <-dh.chReconcilingFinished:
3185 logger.Debugw(ctx, "reconciling has been finished in time",
3186 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003187 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003188 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3189 log.Fields{"device-id": dh.deviceID})
3190 }
3191 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003192 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003193 dh.mutexReconcilingFlag.Unlock()
3194 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003195 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003196 dh.mutexReconcilingFlag.Lock()
3197 if skipOnuConfig {
3198 dh.reconciling = cSkipOnuConfigReconciling
3199 } else {
3200 dh.reconciling = cOnuConfigReconciling
3201 }
3202 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003203}
3204
3205func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3206 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3207 if dh.isReconciling() {
3208 dh.chReconcilingFinished <- true
3209 } else {
3210 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3211 }
3212}
3213
3214func (dh *deviceHandler) isReconciling() bool {
3215 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003216 defer dh.mutexReconcilingFlag.RUnlock()
3217 return dh.reconciling != cNoReconciling
3218}
3219
3220func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3221 dh.mutexReconcilingFlag.RLock()
3222 defer dh.mutexReconcilingFlag.RUnlock()
3223 return dh.reconciling == cSkipOnuConfigReconciling
3224}
3225
3226func (dh *deviceHandler) setDeviceReason(value uint8) {
3227 dh.mutexDeviceReason.Lock()
3228 dh.deviceReason = value
3229 dh.mutexDeviceReason.Unlock()
3230}
3231
3232func (dh *deviceHandler) getDeviceReason() uint8 {
3233 dh.mutexDeviceReason.RLock()
3234 value := dh.deviceReason
3235 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003236 return value
3237}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003238
3239func (dh *deviceHandler) getDeviceReasonString() string {
3240 return deviceReasonMap[dh.getDeviceReason()]
3241}