blob: 6470a8248bb78dcc4f3e8bea46f7fbac37cfb253 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
28 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000031 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
33 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053034 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
36 "github.com/opencord/voltha-lib-go/v4/pkg/log"
37 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050038 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt10d98192021-01-27 15:29:31 +000094type usedOmciConfigFsms int
95
96const (
97 cUploadFsm usedOmciConfigFsms = iota
98 cDownloadFsm
99 cUniLockFsm
100 cUniUnLockFsm
101 cAniConfigFsm
102 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800103 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000104 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
mpagenkof1fc3862021-02-16 10:09:52 +0000107type omciIdleCheckStruct struct {
108 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
109 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110}
111
mpagenkof1fc3862021-02-16 10:09:52 +0000112var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
113 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
119 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000120 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000123const (
124 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000125 drUnset = 0
126 drActivatingOnu = 1
127 drStartingOpenomci = 2
128 drDiscoveryMibsyncComplete = 3
129 drInitialMibDownloaded = 4
130 drTechProfileConfigDownloadSuccess = 5
131 drOmciFlowsPushed = 6
132 drOmciAdminLock = 7
133 drOnuReenabled = 8
134 drStoppingOpenomci = 9
135 drRebooting = 10
136 drOmciFlowsDeleted = 11
137 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000138)
139
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000140var deviceReasonMap = map[uint8]string{
141 drUnset: "unset",
142 drActivatingOnu: "activating-onu",
143 drStartingOpenomci: "starting-openomci",
144 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
145 drInitialMibDownloaded: "initial-mib-downloaded",
146 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
147 drOmciFlowsPushed: "omci-flows-pushed",
148 drOmciAdminLock: "omci-admin-lock",
149 drOnuReenabled: "onu-reenabled",
150 drStoppingOpenomci: "stopping-openomci",
151 drRebooting: "rebooting",
152 drOmciFlowsDeleted: "omci-flows-deleted",
153 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
154}
155
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000156const (
157 cNoReconciling = iota
158 cOnuConfigReconciling
159 cSkipOnuConfigReconciling
160)
161
Himani Chawla6d2ae152020-09-02 13:11:20 +0530162//deviceHandler will interact with the ONU ? device.
163type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164 deviceID string
165 DeviceType string
166 adminState string
167 device *voltha.Device
168 logicalDeviceID string
169 ProxyAddressID string
170 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530171 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000172 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000174 coreProxy adapterif.CoreProxy
175 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530176 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000177
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800178 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800179
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180 pOpenOnuAc *OpenONUAC
181 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530182 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000183 deviceEntrySet chan bool //channel for DeviceEntry set event
184 pOnuOmciDevice *OnuDeviceEntry
185 pOnuTP *onuUniTechProf
186 pOnuMetricsMgr *onuMetricsManager
187 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700188 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000189 exitChannel chan int
190 lockDevice sync.RWMutex
191 pOnuIndication *oop.OnuIndication
192 deviceReason uint8
193 mutexDeviceReason sync.RWMutex
194 pLockStateFsm *lockStateFsm
195 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197 //flowMgr *OpenOltFlowMgr
198 //eventMgr *OpenOltEventMgr
199 //resourceMgr *rsrcMgr.OpenOltResourceMgr
200
201 //discOnus sync.Map
202 //onus sync.Map
203 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000204 collectorIsRunning bool
205 mutexCollectorFlag sync.RWMutex
206 stopCollector chan bool
207 alarmManagerIsRunning bool
208 mutextAlarmManagerFlag sync.RWMutex
209 stopAlarmManager chan bool
210 stopHeartbeatCheck chan bool
211 uniEntityMap map[uint32]*onuUniPort
212 mutexKvStoreContext sync.Mutex
213 lockVlanConfig sync.RWMutex
214 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
215 lockUpgradeFsm sync.RWMutex
216 pOnuUpradeFsm *OnuUpgradeFsm
217 reconciling uint8
218 mutexReconcilingFlag sync.RWMutex
219 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000220 reconcilingFlows bool
221 mutexReconcilingFlowsFlag sync.RWMutex
222 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000223 mutexReadyForOmciConfig sync.RWMutex
224 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000225 deletionInProgress bool
226 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000227 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228}
229
Himani Chawla6d2ae152020-09-02 13:11:20 +0530230//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530231func 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 +0530232 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 dh.coreProxy = cp
234 dh.AdapterProxy = ap
235 dh.EventProxy = ep
236 cloned := (proto.Clone(device)).(*voltha.Device)
237 dh.deviceID = cloned.Id
238 dh.DeviceType = cloned.Type
239 dh.adminState = "up"
240 dh.device = cloned
241 dh.pOpenOnuAc = adapter
242 dh.exitChannel = make(chan int, 1)
243 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000244 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000245 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530247 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530248 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 dh.stopHeartbeatCheck = make(chan bool, 2)
250 //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 +0000251 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530252 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000253 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000254 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000255 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000256 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000257 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000258 dh.reconcilingFlows = false
259 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000260 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000261 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000262
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800263 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
264 dh.pmConfigs = cloned.PmConfigs
265 } /* else {
266 // will be populated when onu_metrics_mananger is initialized.
267 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800268
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269 // Device related state machine
270 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000271 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000273 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
274 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
275 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
276 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
277 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278 },
279 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
281 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
282 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
283 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
284 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
285 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
286 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
287 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 },
289 )
mpagenkoaf801632020-07-03 10:00:42 +0000290
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291 return &dh
292}
293
Himani Chawla6d2ae152020-09-02 13:11:20 +0530294// start save the device to the data model
295func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299}
300
Himani Chawla4d908332020-08-31 12:30:20 +0530301/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530303func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304 logger.Debug("stopping-device-handler")
305 dh.exitChannel <- 1
306}
Himani Chawla4d908332020-08-31 12:30:20 +0530307*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308
309// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311
Girish Gowdrae0140f02021-02-02 16:55:09 -0800312//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000314 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000317 if dh.pDeviceStateFsm.Is(devStNull) {
318 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800322 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
323 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800324 // Now, set the initial PM configuration for that device
325 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
326 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
327 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800328 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331 }
332
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000333}
334
mpagenko057889c2021-01-21 16:51:58 +0000335func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 msgBody := msg.GetBody()
337 omciMsg := &ic.InterAdapterOmciMessage{}
338 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 "device-id": dh.deviceID, "error": err})
341 return err
342 }
343
mpagenko80622a52021-02-09 16:53:23 +0000344 /* 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 +0530345 //assuming omci message content is hex coded!
346 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000349 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000352 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000354 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 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 +0530356 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000358 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530359}
360
Himani Chawla6d2ae152020-09-02 13:11:20 +0530361func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000366
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
371 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if dh.pOnuTP == nil {
373 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000378 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000380 "device-state": dh.getDeviceReasonString()})
381 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000383 //previous state test here was just this one, now extended for more states to reject the SetRequest:
384 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
385 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530386
387 msgBody := msg.GetBody()
388 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
389 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 "device-id": dh.deviceID, "error": err})
392 return err
393 }
394
395 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
397 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400
401 if techProfMsg.UniId > 255 {
402 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
403 techProfMsg.UniId, dh.deviceID))
404 }
405 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800406 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
407 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000408 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800409 return err
410 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530413 // if there has been some change for some uni TechProfilePath
414 //in order to allow concurrent calls to other dh instances we do not wait for execution here
415 //but doing so we can not indicate problems to the caller (who does what with that then?)
416 //by now we just assume straightforward successful execution
417 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
418 // possible problems to the caller later autonomously
419
420 // deadline context to ensure completion of background routines waited for
421 //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 +0530422 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530423 dctx, cancel := context.WithDeadline(context.Background(), deadline)
424
Girish Gowdra041dcb32020-11-16 16:54:30 -0800425 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426 pDevEntry.resetKvProcessingErrorIndication()
427
Himani Chawla26e555c2020-08-31 12:30:20 +0530428 var wg sync.WaitGroup
429 wg.Add(2) // for the 2 go routines to finish
430 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
432 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
433 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000434
Girish Gowdra041dcb32020-11-16 16:54:30 -0800435 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530436 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000437 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530438 return nil
439}
440
Himani Chawla6d2ae152020-09-02 13:11:20 +0530441func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000442 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530443 msg *ic.InterAdapterMessage) error {
444
dbainbri4d3a0dc2020-12-02 00:33:42 +0000445 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000446
dbainbri4d3a0dc2020-12-02 00:33:42 +0000447 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
451 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 if dh.pOnuTP == nil {
453 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000454 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530457 }
458
459 msgBody := msg.GetBody()
460 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
461 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000462 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530463 "device-id": dh.deviceID, "error": err})
464 return err
465 }
466
467 //compare TECH_PROFILE_DOWNLOAD_REQUEST
468 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530470
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471 if delGemPortMsg.UniId > 255 {
472 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
473 delGemPortMsg.UniId, dh.deviceID))
474 }
475 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800476 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
477 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 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 -0800479 return err
480 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530481
mpagenkofc4f56e2020-11-04 17:17:49 +0000482 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483
mpagenkofc4f56e2020-11-04 17:17:49 +0000484 // deadline context to ensure completion of background routines waited for
485 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
486 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487
Girish Gowdra041dcb32020-11-16 16:54:30 -0800488 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000489
mpagenkofc4f56e2020-11-04 17:17:49 +0000490 var wg sync.WaitGroup
491 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000493 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000494 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000495
Girish Gowdra041dcb32020-11-16 16:54:30 -0800496 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530497}
498
Himani Chawla6d2ae152020-09-02 13:11:20 +0530499func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000500 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502
dbainbri4d3a0dc2020-12-02 00:33:42 +0000503 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000504
dbainbri4d3a0dc2020-12-02 00:33:42 +0000505 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000508 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
509 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530510 if dh.pOnuTP == nil {
511 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 }
516
517 msgBody := msg.GetBody()
518 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
519 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000520 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530521 "device-id": dh.deviceID, "error": err})
522 return err
523 }
524
525 //compare TECH_PROFILE_DOWNLOAD_REQUEST
526 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528
529 if delTcontMsg.UniId > 255 {
530 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
531 delTcontMsg.UniId, dh.deviceID))
532 }
533 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800534 tpPath := delTcontMsg.TpPath
535 tpID, err := GetTpIDFromTpPath(tpPath)
536 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000537 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800538 return err
539 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540
dbainbri4d3a0dc2020-12-02 00:33:42 +0000541 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530542 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530543 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 dctx, cancel := context.WithDeadline(context.Background(), deadline)
545
Girish Gowdra041dcb32020-11-16 16:54:30 -0800546 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000547 pDevEntry.resetKvProcessingErrorIndication()
548
Himani Chawla26e555c2020-08-31 12:30:20 +0530549 var wg sync.WaitGroup
550 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530552 cResourceTcont, delTcontMsg.AllocId, &wg)
553 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000554 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
555 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000556
Girish Gowdra041dcb32020-11-16 16:54:30 -0800557 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530558 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530559 return nil
560}
561
Himani Chawla6d2ae152020-09-02 13:11:20 +0530562//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000563// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
564// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000565func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000566 msgID := msg.Header.Id
567 msgType := msg.Header.Type
568 fromTopic := msg.Header.FromTopic
569 toTopic := msg.Header.ToTopic
570 toDeviceID := msg.Header.ToDeviceId
571 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000573 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
574
575 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000576 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000577 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
578 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000579 {
mpagenko057889c2021-01-21 16:51:58 +0000580 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000581 }
mpagenkoaf801632020-07-03 10:00:42 +0000582 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
583 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000584 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000585 }
586 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
587 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000589
mpagenkoaf801632020-07-03 10:00:42 +0000590 }
591 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
592 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000594 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000595 default:
596 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000598 "msgType": msg.Header.Type, "device-id": dh.deviceID})
599 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000600 }
601 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000602}
603
mpagenkodff5dda2020-08-28 11:52:01 +0000604//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
606 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000607 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000609
mpagenko01e726e2020-10-23 09:45:29 +0000610 var retError error = nil
611 //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 +0000612 if apOfFlowChanges.ToRemove != nil {
613 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000614 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000616 "device-id": dh.deviceID})
617 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000618 continue
619 }
620 flowInPort := flow.GetInPort(flowItem)
621 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622 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 +0000623 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
624 continue
625 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000626 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000627 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000628 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000629 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000630 continue
631 } else {
632 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530633 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000634 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
635 loUniPort = uniPort
636 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000638 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
639 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
640 flowInPort, dh.deviceID)
641 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000642 }
643 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000645 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000646 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000648 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000649 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000651 log.Fields{"device-id": dh.deviceID, "error": err})
652 retError = err
653 continue
654 //return err
655 } else { // if last setting succeeds, overwrite possibly previously set error
656 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000657 }
658 }
659 }
660 }
mpagenko01e726e2020-10-23 09:45:29 +0000661 if apOfFlowChanges.ToAdd != nil {
662 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
663 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000664 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000665 "device-id": dh.deviceID})
666 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
667 continue
668 }
669 flowInPort := flow.GetInPort(flowItem)
670 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 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 +0000672 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
673 continue
674 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
675 } else if flowInPort == dh.ponPortNumber {
676 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000678 "device-id": dh.deviceID, "inPort": flowInPort})
679 continue
680 } else {
681 // this is the relevant upstream flow
682 var loUniPort *onuUniPort
683 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
684 loUniPort = uniPort
685 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000687 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
688 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
689 flowInPort, dh.deviceID)
690 continue
691 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
692 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000693 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
694 // if not, we just throw some error here to have an indication about that, if we really need to support that
695 // then we would need to create some means to activate the internal stored flows
696 // after the device gets active automatically (and still with its dependency to the TechProfile)
697 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
698 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000699 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000701 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000702 return fmt.Errorf("improper device state on device %s", dh.deviceID)
703 }
704
mpagenko01e726e2020-10-23 09:45:29 +0000705 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000707 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
708 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000710 //try next flow after processing error
711 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000713 log.Fields{"device-id": dh.deviceID, "error": err})
714 retError = err
715 continue
716 //return err
717 } else { // if last setting succeeds, overwrite possibly previously set error
718 retError = nil
719 }
720 }
721 }
722 }
723 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000724}
725
Himani Chawla6d2ae152020-09-02 13:11:20 +0530726//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000727//following are the expected device states after this activity:
728//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
729// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
731 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000732
mpagenko900ee4b2020-10-12 11:56:34 +0000733 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000734 //note that disableDevice sequences in some 'ONU active' state may yield also
735 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000736 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000737 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000738 //disable-device shall be just a UNi/ONU-G related admin state setting
739 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000740
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000741 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000742 // disable UNI ports/ONU
743 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
744 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000746 } else { //LockStateFSM already init
747 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000748 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000749 }
750 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000752 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000754 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
755 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000757 }
mpagenko01e726e2020-10-23 09:45:29 +0000758 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000759
760 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000762 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300763 }
764}
765
Himani Chawla6d2ae152020-09-02 13:11:20 +0530766//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000767func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
768 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000769
mpagenkoaa3afe92021-05-21 16:20:58 +0000770 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000771 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
772 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
773 // for real ONU's that should have nearly no influence
774 // Note that for real ONU's there is anyway a problematic situation with following sequence:
775 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
776 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
777 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000778 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000779
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000780 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000781 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000782 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000784 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000785 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000786 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000787 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300788}
789
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
791 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000792
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000796 return
797 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000799 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000801 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000803 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000804 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000805 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000806 }
Himani Chawla4d908332020-08-31 12:30:20 +0530807 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000808 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
810 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
811 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
812 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000813 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000815}
816
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
818 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000819
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000821 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000823 if !dh.isSkipOnuConfigReconciling() {
824 dh.stopReconciling(ctx)
825 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 return
827 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000828 dh.pOnuTP.lockTpProcMutex()
829 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000830 pDevEntry.mutexPersOnuConfig.RLock()
831 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000833 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000836 if !dh.isSkipOnuConfigReconciling() {
837 dh.stopReconciling(ctx)
838 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000839 return
840 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000841 techProfsFound := false
842 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000844 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
845 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000846 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000847 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000848 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000849 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000850 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800851 for tpID := range uniData.PersTpPathMap {
852 // deadline context to ensure completion of background routines waited for
853 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
854 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000856
Girish Gowdra041dcb32020-11-16 16:54:30 -0800857 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
858 var wg sync.WaitGroup
859 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
861 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800862 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000863 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800864 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000865 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000866 if len(uniData.PersFlowParams) != 0 {
867 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000868 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000869 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000870 if !techProfsFound {
871 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
872 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000873 if !dh.isSkipOnuConfigReconciling() {
874 dh.stopReconciling(ctx)
875 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000876 return
877 }
878 if dh.isSkipOnuConfigReconciling() {
879 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
880 }
881 if !flowsFound {
882 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
883 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000884 if !dh.isSkipOnuConfigReconciling() {
885 dh.stopReconciling(ctx)
886 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000887 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000888}
889
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
891 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000892
dbainbri4d3a0dc2020-12-02 00:33:42 +0000893 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000894 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000896 if !dh.isSkipOnuConfigReconciling() {
897 dh.stopReconciling(ctx)
898 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000899 return
900 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000901 pDevEntry.mutexPersOnuConfig.RLock()
902 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000903
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000904 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000906 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000907 if !dh.isSkipOnuConfigReconciling() {
908 dh.stopReconciling(ctx)
909 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000910 return
911 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000912 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000913 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000914 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
915 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000916 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000917 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918 continue
919 }
920 if len(uniData.PersTpPathMap) == 0 {
921 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
922 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000923 // It doesn't make sense to configure any flows if no TPs are available
924 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000925 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000926 var uniPort *onuUniPort
927 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000929 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000930 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
931 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000932 if !dh.isSkipOnuConfigReconciling() {
933 dh.stopReconciling(ctx)
934 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000935 return
936 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000937 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200938 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000939 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000940 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000941 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000942 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200943 // If this is the last flow for the device we need to announce it the waiting
944 // chReconcilingFlowsFinished channel
945 if flowsProcessed == len(uniData.PersFlowParams)-1 {
946 lastFlowToReconcile = true
947 }
mpagenko01e726e2020-10-23 09:45:29 +0000948 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000949 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000952 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200953 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000954 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000955 }
mpagenkof1fc3862021-02-16 10:09:52 +0000956 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000957 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000958 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000960 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200961 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000962 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000963 }
964 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000965 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000966 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000967 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
968 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
969 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200970 // this can't be used as global finished reconciling flag because
971 // assumes is getting called before the state machines for the last flow is completed,
972 // while this is not guaranteed.
973 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000974 }
975 if !flowsFound {
976 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
977 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000978 if !dh.isSkipOnuConfigReconciling() {
979 dh.stopReconciling(ctx)
980 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000981 return
982 }
983 if dh.isSkipOnuConfigReconciling() {
984 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000985 }
986}
987
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000988func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
989 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000990 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000991}
992
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
994 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000995
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000998 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001000 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001001 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001002
1003 // deadline context to ensure completion of background routines waited for
1004 //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 +05301005 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001007
1008 pDevEntry.resetKvProcessingErrorIndication()
1009
1010 var wg sync.WaitGroup
1011 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1013 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001014
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001015 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001016 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001017}
1018
mpagenko15ff4a52021-03-02 10:09:20 +00001019//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1020// before this change here return like this was used:
1021// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1022//was and is called in background - error return does not make sense
1023func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1024 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1025 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001026 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001027 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001028 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001029 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301030 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001031 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001032 return
Himani Chawla4d908332020-08-31 12:30:20 +05301033 }
mpagenko01e726e2020-10-23 09:45:29 +00001034
1035 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001036 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001037
dbainbri4d3a0dc2020-12-02 00:33:42 +00001038 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001039 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001040 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001041 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001042 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001044 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001045 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001047 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001048 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001049 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001050 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1051 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1052 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1053 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001054}
1055
mpagenkoc8bba412021-01-15 15:38:44 +00001056//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001057func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1058 apDownloadManager *adapterDownloadManager) error {
1059 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001060 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001061
1062 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001063 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1064 if pDevEntry == nil {
1065 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1066 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1067 }
1068
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001069 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001070 var inactiveImageID uint16
1071 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1072 dh.lockUpgradeFsm.Lock()
1073 defer dh.lockUpgradeFsm.Unlock()
1074 if dh.pOnuUpradeFsm == nil {
1075 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1076 if err == nil {
1077 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1078 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1079 "device-id": dh.deviceID, "error": err})
1080 }
1081 } else {
1082 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001083 "device-id": dh.deviceID, "error": err})
1084 }
mpagenko15ff4a52021-03-02 10:09:20 +00001085 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1086 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1087 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1088 if pUpgradeStatemachine != nil {
1089 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1090 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1091 "device-id": dh.deviceID, "error": err})
1092 }
1093 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1094 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1095 // for now a second start of download should work again
1096 } else { //should never occur
1097 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1098 "device-id": dh.deviceID})
1099 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001100 }
mpagenko80622a52021-02-09 16:53:23 +00001101 }
mpagenko15ff4a52021-03-02 10:09:20 +00001102 } else {
1103 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1104 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001105 }
1106 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001107 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1108 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001109 }
1110 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001111}
1112
mpagenkoc26d4c02021-05-06 14:27:57 +00001113//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1114// after the OnuImage has been downloaded to the adapter, called in background
1115func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1116 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1117
1118 var err error
1119 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1120 if pDevEntry == nil {
1121 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1122 return
1123 }
1124
1125 var inactiveImageID uint16
1126 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1127 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1128 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1129 dh.lockUpgradeFsm.Lock()
1130 defer dh.lockUpgradeFsm.Unlock()
1131 if dh.pOnuUpradeFsm == nil {
1132 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1133 // but none yet defined
1134 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1135 if err == nil {
1136 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1137 apImageRequest, apDownloadManager, aImageIdentifier, dh.pOpenOnuAc.dlToOnuTimeout4M); err != nil {
1138 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1139 "device-id": dh.deviceID, "error": err})
1140 return
1141 }
1142 } else {
1143 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1144 "device-id": dh.deviceID, "error": err})
1145 }
1146 return
1147 }
1148 //OnuSw upgrade already running - restart (with possible abort of running)
1149 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1150 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1151 if pUpgradeStatemachine != nil {
1152 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1153 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1154 "device-id": dh.deviceID, "error": err})
1155 return
1156 }
1157 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1158 // for now a second start of download should work again - must still be initiated by user
1159 } else { //should never occur
1160 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1161 "device-id": dh.deviceID})
1162 }
1163 return
1164 }
1165 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1166 "device-id": dh.deviceID, "error": err})
1167}
1168
1169//onuSwActivateRequest ensures activation of the requested image with commit options
1170func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context, aVersion string, aCommitRequest bool) {
1171 var err error
1172 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1173 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1174 // 2.) activation of the inactive image
1175
1176 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1177 if pDevEntry == nil {
1178 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1179 return
1180 }
1181 dh.lockUpgradeFsm.RLock()
1182 if dh.pOnuUpradeFsm != nil {
1183 dh.lockUpgradeFsm.RUnlock()
1184 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1185 dh.deviceID, dh.deviceID)
1186 if getErr != nil || onuVolthaDevice == nil {
1187 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
1188 return
1189 }
1190 // use the OnuVendor identification from this device for the internal unique name
1191 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1192 // 1.) check a started upgrade process and rely the activation request to it
1193 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
1194 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1195 "device-id": dh.deviceID, "error": err})
1196 } else {
1197 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1198 "device-id": dh.deviceID, "image-id": imageIdentifier})
1199 }
1200 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
1201 // (even though parameter setting is not accepted)
1202 return
1203 } //else
1204 dh.lockUpgradeFsm.RUnlock()
1205
1206 // 2.) check if requested image-version equals the inactive one and start its activation
1207 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1208 var inactiveImageID uint16
1209 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1210 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1211 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
1212 return
1213 }
1214 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1215 if err == nil {
1216 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1217 inactiveImageID, aCommitRequest); err != nil {
1218 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1219 "device-id": dh.deviceID, "error": err})
1220 return
1221 }
1222 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1223 "device-id": dh.deviceID, "image-version": aVersion})
1224 return
1225 } //else
1226 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1227 "device-id": dh.deviceID, "error": err})
1228}
1229
1230//onuSwCommitRequest ensures commitment of the requested image
1231func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context, aVersion string) {
1232 var err error
1233 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1234 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1235 // 2.) commitment of the active image
1236
1237 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1238 if pDevEntry == nil {
1239 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1240 return
1241 }
1242 dh.lockUpgradeFsm.RLock()
1243 if dh.pOnuUpradeFsm != nil {
1244 dh.lockUpgradeFsm.RUnlock()
1245 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1246 dh.deviceID, dh.deviceID)
1247 if getErr != nil || onuVolthaDevice == nil {
1248 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
1249 return
1250 }
1251 // use the OnuVendor identification from this device for the internal unique name
1252 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1253 // 1.) check a started upgrade process and rely the commitment request to it
1254 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
1255 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1256 "device-id": dh.deviceID, "error": err})
1257 } else {
1258 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1259 "device-id": dh.deviceID, "image-id": imageIdentifier})
1260 }
1261 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
1262 // (even though parameter setting is not accepted)
1263 return
1264 } //else
1265 dh.lockUpgradeFsm.RUnlock()
1266
1267 // 2.) check if requested image-version equals the inactive one and start its commitment
1268 var activeImageID uint16
1269 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1270 logger.Errorw(ctx, "get active image failed", log.Fields{
1271 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
1272 return
1273 }
1274 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1275 if err == nil {
1276 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1277 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1278 "device-id": dh.deviceID, "error": err})
1279 return
1280 }
1281 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1282 "device-id": dh.deviceID, "image-version": aVersion})
1283 return
1284 } //else
1285 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1286 "device-id": dh.deviceID, "error": err})
1287}
1288
mpagenkoaa3afe92021-05-21 16:20:58 +00001289func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1290 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1291 pDeviceImageState.DeviceId = dh.deviceID
1292 pDeviceImageState.ImageState.Version = aImageIdentifier
1293 dh.lockUpgradeFsm.RLock()
1294 if dh.pOnuUpradeFsm != nil {
1295 dh.lockUpgradeFsm.RUnlock()
1296 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err != nil {
1297 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1298 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1299 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1300 } else {
1301 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1302 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1303 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1304 }
1305 } else {
1306 dh.lockUpgradeFsm.RUnlock()
1307 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1308 if dh.upgradeSuccess {
1309 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1310 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1311 } else {
1312 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1313 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1314 }
1315 }
1316}
1317
1318func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1319 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1320 pDeviceImageState.DeviceId = dh.deviceID
1321 pDeviceImageState.ImageState.Version = aImageIdentifier
1322 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1323 dh.lockUpgradeFsm.RLock()
1324 if dh.pOnuUpradeFsm != nil {
1325 dh.lockUpgradeFsm.RUnlock()
1326 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1327 // by now just straightforward assume this to be true
1328 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1329 //nolint:misspell
1330 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1331 //nolint:misspell
1332 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1333 } else {
1334 dh.lockUpgradeFsm.RUnlock()
1335 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1336 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1337 }
1338}
1339
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001340func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1341
1342 var onuImageStatus *OnuImageStatus
1343
1344 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1345 if pDevEntry != nil {
1346 onuImageStatus = NewOnuImageStatus(pDevEntry)
1347 pDevEntry.mutexOnuImageStatus.Lock()
1348 pDevEntry.pOnuImageStatus = onuImageStatus
1349 pDevEntry.mutexOnuImageStatus.Unlock()
1350
1351 } else {
1352 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1353 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1354 }
1355 images, err := onuImageStatus.getOnuImageStatus(ctx)
1356 pDevEntry.mutexOnuImageStatus.Lock()
1357 pDevEntry.pOnuImageStatus = nil
1358 pDevEntry.mutexOnuImageStatus.Unlock()
1359 return images, err
1360}
1361
Himani Chawla6d2ae152020-09-02 13:11:20 +05301362// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001363// #####################################################################################
1364
1365// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301366// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001367
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1369 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 +00001370}
1371
1372// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001373func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001374
dbainbri4d3a0dc2020-12-02 00:33:42 +00001375 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001376 var err error
1377
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001378 // populate what we know. rest comes later after mib sync
1379 dh.device.Root = false
1380 dh.device.Vendor = "OpenONU"
1381 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001382 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001383 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001384
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001385 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001386
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001387 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001388 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1389 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301390 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001392 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001393 log.Fields{"device-id": dh.deviceID})
1394 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001395
Himani Chawla4d908332020-08-31 12:30:20 +05301396 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001397 dh.ponPortNumber = dh.device.ParentPortNo
1398
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001399 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1400 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1401 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001402 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001403 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301404 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001405
1406 /*
1407 self._pon = PonPort.create(self, self._pon_port_number)
1408 self._pon.add_peer(self.parent_id, self._pon_port_number)
1409 self.logger.debug('adding-pon-port-to-agent',
1410 type=self._pon.get_port().type,
1411 admin_state=self._pon.get_port().admin_state,
1412 oper_status=self._pon.get_port().oper_status,
1413 )
1414 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001415 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001416 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001417 var ponPortNo uint32 = 1
1418 if dh.ponPortNumber != 0 {
1419 ponPortNo = dh.ponPortNumber
1420 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001421
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001422 pPonPort := &voltha.Port{
1423 PortNo: ponPortNo,
1424 Label: fmt.Sprintf("pon-%d", ponPortNo),
1425 Type: voltha.Port_PON_ONU,
1426 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301427 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001428 PortNo: ponPortNo}}, // Peer port is parent's port number
1429 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1431 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001432 e.Cancel(err)
1433 return
1434 }
1435 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001437 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001439}
1440
1441// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001443
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001445 var err error
1446 /*
1447 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1448 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1449 return nil
1450 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1452 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001453 e.Cancel(err)
1454 return
1455 }
1456
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001457 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001458 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001459 // reconcilement will be continued after mib download is done
1460 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001461
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001462 /*
1463 ############################################################################
1464 # Setup Alarm handler
1465 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1466 device.serial_number)
1467 ############################################################################
1468 # Setup PM configuration for this device
1469 # Pass in ONU specific options
1470 kwargs = {
1471 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1472 'heartbeat': self.heartbeat,
1473 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1474 }
1475 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1476 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1477 self.logical_device_id, device.serial_number,
1478 grouped=True, freq_override=False, **kwargs)
1479 pm_config = self._pm_metrics.make_proto()
1480 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1481 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1482 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1483
1484 # Note, ONU ID and UNI intf set in add_uni_port method
1485 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1486 ani_ports=[self._pon])
1487
1488 # Code to Run OMCI Test Action
1489 kwargs_omci_test_action = {
1490 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1491 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1492 }
1493 serial_number = device.serial_number
1494 self._test_request = OmciTestRequest(self.core_proxy,
1495 self.omci_agent, self.device_id,
1496 AniG, serial_number,
1497 self.logical_device_id,
1498 exclusive=False,
1499 **kwargs_omci_test_action)
1500
1501 self.enabled = True
1502 else:
1503 self.logger.info('onu-already-activated')
1504 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001505
dbainbri4d3a0dc2020-12-02 00:33:42 +00001506 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001507}
1508
1509// doStateConnected get the device info and update to voltha core
1510// for comparison of the original method (not that easy to uncomment): compare here:
1511// voltha-openolt-adapter/adaptercore/device_handler.go
1512// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001513func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001514
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301516 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001517 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001519}
1520
1521// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001523
dbainbri4d3a0dc2020-12-02 00:33:42 +00001524 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301525 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001528
1529 /*
1530 // Synchronous call to update device state - this method is run in its own go routine
1531 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1532 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001533 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 +00001534 return err
1535 }
1536 return nil
1537 */
1538}
1539
1540// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001542
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001544 var err error
1545
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001546 device := dh.device
1547 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001548 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001550 e.Cancel(err)
1551 return
1552 }
1553
1554 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001555 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001556 /*
1557 // Update the all ports state on that device to disable
1558 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001559 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001560 return er
1561 }
1562
1563 //Update the device oper state and connection status
1564 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1565 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1566 dh.device = cloned
1567
1568 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001569 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570 return er
1571 }
1572
1573 //get the child device for the parent device
1574 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1575 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001576 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001577 return err
1578 }
1579 for _, onuDevice := range onuDevices.Items {
1580
1581 // Update onu state as down in onu adapter
1582 onuInd := oop.OnuIndication{}
1583 onuInd.OperState = "down"
1584 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1585 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1586 if er != nil {
1587 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001588 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 //Do not return here and continue to process other ONUs
1590 }
1591 }
1592 // * Discovered ONUs entries need to be cleared , since after OLT
1593 // is up, it starts sending discovery indications again* /
1594 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001595 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001596 return nil
1597 */
Himani Chawla4d908332020-08-31 12:30:20 +05301598 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001599 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601}
1602
Himani Chawla6d2ae152020-09-02 13:11:20 +05301603// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001604// #################################################################################
1605
1606// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301607// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001608
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001609//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001611 dh.lockDevice.RLock()
1612 pOnuDeviceEntry := dh.pOnuOmciDevice
1613 if aWait && pOnuDeviceEntry == nil {
1614 //keep the read sema short to allow for subsequent write
1615 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001617 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1618 // so it might be needed to wait here for that event with some timeout
1619 select {
1620 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001622 return nil
1623 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001625 // if written now, we can return the written value without sema
1626 return dh.pOnuOmciDevice
1627 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001628 }
mpagenko3af1f032020-06-10 08:53:41 +00001629 dh.lockDevice.RUnlock()
1630 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001631}
1632
Himani Chawla6d2ae152020-09-02 13:11:20 +05301633//setOnuDeviceEntry sets the ONU device entry within the handler
1634func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001635 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636 dh.lockDevice.Lock()
1637 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001638 dh.pOnuOmciDevice = apDeviceEntry
1639 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001640 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301641 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001642 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643}
1644
Himani Chawla6d2ae152020-09-02 13:11:20 +05301645//addOnuDeviceEntry creates a new ONU device or returns the existing
1646func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650 if deviceEntry == nil {
1651 /* costum_me_map in python code seems always to be None,
1652 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1653 /* also no 'clock' argument - usage open ...*/
1654 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001655 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001656 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001657 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301658 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001659 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001661 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001662 // fire deviceEntry ready event to spread to possibly waiting processing
1663 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667 }
1668 // might be updated with some error handling !!!
1669 return nil
1670}
1671
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1673 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001674 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1675
1676 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001679 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001681 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1682 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001683 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 if err := dh.storePersistentData(ctx); err != nil {
1685 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001686 log.Fields{"device-id": dh.deviceID, "err": err})
1687 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001689 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001691 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1692 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001694 }
1695 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001697 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001698
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001699 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001700 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001701 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 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 +00001703 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001704 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001705 } else {
1706 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001707 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001708 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001709 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1710 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1711 // 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 +00001712 // 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 +00001713 // so let's just try to keep it simple ...
1714 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001716 if err != nil || device == nil {
1717 //TODO: needs to handle error scenarios
1718 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1719 return errors.New("Voltha Device not found")
1720 }
1721 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001722
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 return err
mpagenko3af1f032020-06-10 08:53:41 +00001725 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001727 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728
1729 /* this might be a good time for Omci Verify message? */
1730 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001732 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001733 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735
1736 /* give the handler some time here to wait for the OMCi verification result
1737 after Timeout start and try MibUpload FSM anyway
1738 (to prevent stopping on just not supported OMCI verification from ONU) */
1739 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001740 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001742 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001744 }
1745
1746 /* In py code it looks earlier (on activate ..)
1747 # Code to Run OMCI Test Action
1748 kwargs_omci_test_action = {
1749 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1750 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1751 }
1752 serial_number = device.serial_number
1753 self._test_request = OmciTestRequest(self.core_proxy,
1754 self.omci_agent, self.device_id,
1755 AniG, serial_number,
1756 self.logical_device_id,
1757 exclusive=False,
1758 **kwargs_omci_test_action)
1759 ...
1760 # Start test requests after a brief pause
1761 if not self._test_request_started:
1762 self._test_request_started = True
1763 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1764 reactor.callLater(tststart, self._test_request.start_collector)
1765
1766 */
1767 /* which is then: in omci_test_request.py : */
1768 /*
1769 def start_collector(self, callback=None):
1770 """
1771 Start the collection loop for an adapter if the frequency > 0
1772
1773 :param callback: (callable) Function to call to collect PM data
1774 """
1775 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1776 if callback is None:
1777 callback = self.perform_test_omci
1778
1779 if self.lc is None:
1780 self.lc = LoopingCall(callback)
1781
1782 if self.default_freq > 0:
1783 self.lc.start(interval=self.default_freq / 10)
1784
1785 def perform_test_omci(self):
1786 """
1787 Perform the initial test request
1788 """
1789 ani_g_entities = self._device.configuration.ani_g_entities
1790 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1791 is not None else None
1792 self._entity_id = ani_g_entities_ids[0]
1793 self.logger.info('perform-test', entity_class=self._entity_class,
1794 entity_id=self._entity_id)
1795 try:
1796 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1797 result = yield self._device.omci_cc.send(frame)
1798 if not result.fields['omci_message'].fields['success_code']:
1799 self.logger.info('Self-Test Submitted Successfully',
1800 code=result.fields[
1801 'omci_message'].fields['success_code'])
1802 else:
1803 raise TestFailure('Test Failure: {}'.format(
1804 result.fields['omci_message'].fields['success_code']))
1805 except TimeoutError as e:
1806 self.deferred.errback(failure.Failure(e))
1807
1808 except Exception as e:
1809 self.logger.exception('perform-test-Error', e=e,
1810 class_id=self._entity_class,
1811 entity_id=self._entity_id)
1812 self.deferred.errback(failure.Failure(e))
1813
1814 */
1815
1816 // PM related heartbeat??? !!!TODO....
1817 //self._heartbeat.enabled = True
1818
mpagenko1cc3cb42020-07-27 15:24:38 +00001819 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1820 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1821 * 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 +05301822 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001823 */
1824 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001825 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001826 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001827 if pMibUlFsm.Is(ulStDisabled) {
1828 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 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 +00001830 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301831 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301833 //Determine ONU status and start/re-start MIB Synchronization tasks
1834 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001835 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301836 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001837 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 +00001838 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001839 }
Himani Chawla4d908332020-08-31 12:30:20 +05301840 } else {
1841 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 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 +00001843 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301844 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001846 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001847 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001849 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001850 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001851 }
1852 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001854 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001855 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001856
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001857 if !dh.getCollectorIsRunning() {
1858 // Start PM collector routine
1859 go dh.startCollector(ctx)
1860 }
Himani Chawla1472c682021-03-17 17:11:14 +05301861 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301862 go dh.startAlarmManager(ctx)
1863 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301864
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001865 return nil
1866}
1867
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001869 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001870 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001871 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001873
mpagenko900ee4b2020-10-12 11:56:34 +00001874 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1875 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1876 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001877 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001879 log.Fields{"device-id": dh.deviceID, "error": err})
1880 // abort: system behavior is just unstable ...
1881 return err
1882 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001883 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 _ = 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 +00001885
1886 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1887 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1888 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001890 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001892 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001893 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001895
1896 //TODO!!! remove existing traffic profiles
1897 /* from py code, if TP's exist, remove them - not yet implemented
1898 self._tp = dict()
1899 # Let TP download happen again
1900 for uni_id in self._tp_service_specific_task:
1901 self._tp_service_specific_task[uni_id].clear()
1902 for uni_id in self._tech_profile_download_done:
1903 self._tech_profile_download_done[uni_id].clear()
1904 */
1905
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001907
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001908 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001909
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001911 // abort: system behavior is just unstable ...
1912 return err
1913 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001915 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001917 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001918 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001920 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001921 // abort: system behavior is just unstable ...
1922 return err
1923 }
1924 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001926 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001927 return nil
1928}
1929
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001930func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001931 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1932 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1933 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1934 // and using the stop/reset event should never harm
1935
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001937 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001939 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1940 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001941 if pDevEntry.PDevOmciCC != nil {
1942 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1943 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001944 pDevEntry.mutexOnuImageStatus.RLock()
1945 if pDevEntry.pOnuImageStatus != nil {
1946 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
1947 }
1948 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001949
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001950 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001951 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001952 }
1953 //MibDownload may run
1954 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1955 if pMibDlFsm != nil {
1956 _ = pMibDlFsm.Event(dlEvReset)
1957 }
1958 //port lock/unlock FSM's may be active
1959 if dh.pUnlockStateFsm != nil {
1960 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1961 }
1962 if dh.pLockStateFsm != nil {
1963 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1964 }
1965 //techProfile related PonAniConfigFsm FSM may be active
1966 if dh.pOnuTP != nil {
1967 // should always be the case here
1968 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1969 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001970 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001971 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001972 }
mpagenko900ee4b2020-10-12 11:56:34 +00001973 }
1974 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001975 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001976 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001977 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1978 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001979 dh.lockVlanConfig.RUnlock()
1980 //reset of all Fsm is always accompanied by global persistency data removal
1981 // no need to remove specific data
1982 pVlanFilterFsm.RequestClearPersistency(false)
1983 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001984 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001985 } else {
1986 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001987 }
1988 }
1989 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001990 if dh.getCollectorIsRunning() {
1991 // Stop collector routine
1992 dh.stopCollector <- true
1993 }
Himani Chawla1472c682021-03-17 17:11:14 +05301994 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301995 dh.stopAlarmManager <- true
1996 }
1997
mpagenko80622a52021-02-09 16:53:23 +00001998 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00001999 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002000 dh.lockUpgradeFsm.RLock()
2001 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002002 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002003 }
2004 dh.lockUpgradeFsm.RUnlock()
2005
mpagenko7d6bb022021-03-11 15:07:55 +00002006 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002007 return nil
2008}
2009
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2011 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 +05302012
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002013 // store persistent data collected during MIB upload processing
2014 if err := dh.storePersistentData(ctx); err != nil {
2015 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2016 log.Fields{"device-id": dh.deviceID, "err": err})
2017 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002018 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002019 dh.addAllUniPorts(ctx)
2020
mpagenkoa40e99a2020-11-17 13:50:39 +00002021 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2022 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2023 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2024 * disable/enable toggling here to allow traffic
2025 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2026 * like the py comment says:
2027 * # start by locking all the unis till mib sync and initial mib is downloaded
2028 * # this way we can capture the port down/up events when we are ready
2029 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302030
mpagenkoa40e99a2020-11-17 13:50:39 +00002031 // Init Uni Ports to Admin locked state
2032 // *** should generate UniLockStateDone event *****
2033 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002034 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002035 } else { //LockStateFSM already init
2036 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002037 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002038 }
2039}
2040
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2042 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302043 /* Mib download procedure -
2044 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2045 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002047 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002048 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002049 return
2050 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302051 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2052 if pMibDlFsm != nil {
2053 if pMibDlFsm.Is(dlStDisabled) {
2054 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 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 +05302056 // maybe try a FSM reset and then again ... - TODO!!!
2057 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302059 // maybe use more specific states here for the specific download steps ...
2060 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302062 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302064 //Begin MIB data download (running autonomously)
2065 }
2066 }
2067 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002069 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302070 // maybe try a FSM reset and then again ... - TODO!!!
2071 }
2072 /***** Mib download started */
2073 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302075 }
2076}
2077
dbainbri4d3a0dc2020-12-02 00:33:42 +00002078func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2079 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302080 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002081 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002083 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002084 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2085 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2086 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2087 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002088 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302089 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2090 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302092 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302094 }
2095 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302097 log.Fields{"device-id": dh.deviceID})
2098 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002099 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002100
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002101 if !dh.getCollectorIsRunning() {
2102 // Start PM collector routine
2103 go dh.startCollector(ctx)
2104 }
2105 if !dh.getAlarmManagerIsRunning(ctx) {
2106 go dh.startAlarmManager(ctx)
2107 }
2108
Girish Gowdrae0140f02021-02-02 16:55:09 -08002109 // Initialize classical L2 PM Interval Counters
2110 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2111 // There is no way we should be landing here, but if we do then
2112 // there is nothing much we can do about this other than log error
2113 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2114 }
2115
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002116 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002117
2118 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2119 if pDevEntry == nil {
2120 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2121 return
2122 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002123 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002124 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002125 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002126 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2127 log.Fields{"device-id": dh.deviceID})
2128 go dh.reconcileDeviceTechProf(ctx)
2129 // reconcilement will be continued after ani config is done
2130 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002131 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002132 // *** should generate UniUnlockStateDone event *****
2133 if dh.pUnlockStateFsm == nil {
2134 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2135 } else { //UnlockStateFSM already init
2136 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2137 dh.runUniLockFsm(ctx, false)
2138 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302139 }
2140}
2141
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2143 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302144
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002145 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002146 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002147 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2149 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002150 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002152 return
2153 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002154 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002155 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002156 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 if err := dh.storePersistentData(ctx); err != nil {
2158 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002159 log.Fields{"device-id": dh.deviceID, "err": err})
2160 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302161 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002162 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 +05302163 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002165 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302166 }
2167}
2168
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2170 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002171 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002173 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2174 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002176 }
2177
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002179 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002181
2182 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002183 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002184
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002186 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002188 return
2189 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002190 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002191 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002192 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 if err := dh.storePersistentData(ctx); err != nil {
2194 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002195 log.Fields{"device-id": dh.deviceID, "err": err})
2196 }
mpagenko900ee4b2020-10-12 11:56:34 +00002197}
2198
dbainbri4d3a0dc2020-12-02 00:33:42 +00002199func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2200 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002201 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002203 voltha.OperStatus_ACTIVE); err != nil {
2204 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002206 }
2207
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002209 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002210 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002212
2213 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002215
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002217 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002219 return
2220 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002221 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002222 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002223 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 if err := dh.storePersistentData(ctx); err != nil {
2225 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002226 log.Fields{"device-id": dh.deviceID, "err": err})
2227 }
mpagenko900ee4b2020-10-12 11:56:34 +00002228}
2229
dbainbri4d3a0dc2020-12-02 00:33:42 +00002230func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002231 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002232 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002233 // attention: the device reason update is done based on ONU-UNI-Port related activity
2234 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002235 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002236 // 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 +00002237 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302238 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002239 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002241 }
2242 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002243 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002244 // attention: the device reason update is done based on ONU-UNI-Port related activity
2245 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002246 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002247 // 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 +00002248 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002249 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002250 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302251}
2252
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2254 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002255 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302256 // attention: the device reason update is done based on ONU-UNI-Port related activity
2257 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302258
mpagenkof1fc3862021-02-16 10:09:52 +00002259 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002260 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002261 // which may be the case from some previous actvity on another UNI Port of the ONU
2262 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002263 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2264 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002265 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002266 }
2267 }
2268 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002269 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002270 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002271 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002272 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302273 }
mpagenkof1fc3862021-02-16 10:09:52 +00002274
2275 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2276 //events that request KvStore write
2277 if err := dh.storePersistentData(ctx); err != nil {
2278 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2279 log.Fields{"device-id": dh.deviceID, "err": err})
2280 }
2281 } else {
2282 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2283 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002284 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302285}
2286
Himani Chawla6d2ae152020-09-02 13:11:20 +05302287//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302289 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002290 case MibDatabaseSync:
2291 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002293 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002294 case UniLockStateDone:
2295 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002297 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002298 case MibDownloadDone:
2299 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002300 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002301 }
2302 case UniUnlockStateDone:
2303 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002304 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002305 }
mpagenko900ee4b2020-10-12 11:56:34 +00002306 case UniEnableStateDone:
2307 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002309 }
2310 case UniDisableStateDone:
2311 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002313 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002314 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002315 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002317 }
mpagenkof1fc3862021-02-16 10:09:52 +00002318 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002319 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002321 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002322 case OmciOnuSwUpgradeDone:
2323 {
2324 dh.upgradeSuccess = true
2325 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002326 default:
2327 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002329 }
2330 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002331}
2332
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002334 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302336 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002337 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002338 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002339 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302340 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002342 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002344 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002345 //store UniPort with the System-PortNumber key
2346 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002347 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002348 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2350 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002351 } //error logging already within UniPort method
2352 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002354 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002355 }
2356 }
2357}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002358
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002359func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2360 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2361 if pDevEntry == nil {
2362 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2363 return
2364 }
2365 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2366 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2367 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2368 for _, mgmtEntityID := range pptpInstKeys {
2369 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2370 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2371 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2372 i++
2373 }
2374 } else {
2375 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2376 }
2377 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2378 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2379 for _, mgmtEntityID := range veipInstKeys {
2380 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2381 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2382 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2383 i++
2384 }
2385 } else {
2386 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2387 }
2388 if i == 0 {
2389 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2390 }
2391}
2392
mpagenko3af1f032020-06-10 08:53:41 +00002393// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002395 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302396 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002397 // with following remark:
2398 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2399 // # load on the core
2400
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002401 // 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 +00002402
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002403 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002404 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302405 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002406 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302407 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002408 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002409 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 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 +00002411 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002413 }
mpagenko3af1f032020-06-10 08:53:41 +00002414 }
2415 }
2416}
2417
2418// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002419func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002420 // compare enableUniPortStateUpdate() above
2421 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2422 for uniNo, uniPort := range dh.uniEntityMap {
2423 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302424 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002425 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302426 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002427 if !dh.isReconciling() {
2428 //maybe also use getter functions on uniPort - perhaps later ...
2429 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2430 } else {
2431 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2432 }
2433
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002434 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002435 }
2436}
2437
2438// ONU_Active/Inactive announcement on system KAFKA bus
2439// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002441 var de voltha.DeviceEvent
2442 eventContext := make(map[string]string)
2443 //Populating event context
2444 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002446 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302448 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002449 return //TODO with VOL-3045: rw-core is unresponsive: report error and/or perform self-initiated onu-reset?
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002450 }
2451 oltSerialNumber := parentDevice.SerialNumber
2452
2453 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2454 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2455 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302456 eventContext["olt-serial-number"] = oltSerialNumber
2457 eventContext["device-id"] = aDeviceID
2458 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002459 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002460 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002461
2462 /* Populating device event body */
2463 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302464 de.ResourceId = aDeviceID
2465 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002466 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2467 de.Description = fmt.Sprintf("%s Event - %s - %s",
2468 cEventObjectType, cOnuActivatedEvent, "Raised")
2469 } else {
2470 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2471 de.Description = fmt.Sprintf("%s Event - %s - %s",
2472 cEventObjectType, cOnuActivatedEvent, "Cleared")
2473 }
2474 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2476 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302477 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002478 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302480 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002481}
2482
Himani Chawla4d908332020-08-31 12:30:20 +05302483// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002484func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002485 chLSFsm := make(chan Message, 2048)
2486 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302487 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002489 sFsmName = "LockStateFSM"
2490 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002491 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002492 sFsmName = "UnLockStateFSM"
2493 }
mpagenko3af1f032020-06-10 08:53:41 +00002494
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002496 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002498 return
2499 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002501 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002502 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302503 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002504 dh.pLockStateFsm = pLSFsm
2505 } else {
2506 dh.pUnlockStateFsm = pLSFsm
2507 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002509 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002510 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002511 }
2512}
2513
2514// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002515func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002516 /* Uni Port lock/unlock procedure -
2517 ***** should run via 'adminDone' state and generate the argument requested event *****
2518 */
2519 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302520 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002521 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2522 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2523 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002524 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302525 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002526 }
2527 } else {
2528 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2529 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2530 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002531 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302532 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002533 }
2534 }
2535 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002536 if pLSStatemachine.Is(uniStDisabled) {
2537 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002538 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002539 // maybe try a FSM reset and then again ... - TODO!!!
2540 } else {
2541 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002543 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002544 }
2545 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002547 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002548 // maybe try a FSM reset and then again ... - TODO!!!
2549 }
2550 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002551 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002552 // maybe try a FSM reset and then again ... - TODO!!!
2553 }
2554}
2555
mpagenko80622a52021-02-09 16:53:23 +00002556// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002557func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002558 //in here lockUpgradeFsm is already locked
2559 chUpgradeFsm := make(chan Message, 2048)
2560 var sFsmName = "OnuSwUpgradeFSM"
2561 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002562 if apDevEntry.PDevOmciCC == nil {
2563 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2564 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002565 }
mpagenko15ff4a52021-03-02 10:09:20 +00002566 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002567 sFsmName, chUpgradeFsm)
2568 if dh.pOnuUpradeFsm != nil {
2569 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2570 if pUpgradeStatemachine != nil {
2571 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002572 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002573 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2574 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2575 // maybe try a FSM reset and then again ... - TODO!!!
2576 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2577 }
2578 /***** LockStateFSM started */
2579 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2580 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2581 } else {
2582 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2583 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2584 // maybe try a FSM reset and then again ... - TODO!!!
2585 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2586 }
2587 } else {
2588 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2589 // maybe try a FSM reset and then again ... - TODO!!!
2590 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2591 }
2592 } else {
2593 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2594 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2595 }
2596 return nil
2597}
2598
2599// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2600func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2601 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2602 "device-id": dh.deviceID})
2603 dh.lockUpgradeFsm.Lock()
2604 defer dh.lockUpgradeFsm.Unlock()
2605 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2606}
2607
mpagenko15ff4a52021-03-02 10:09:20 +00002608// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2609func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2610 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2611 if pDevEntry == nil {
2612 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2613 return
2614 }
2615
2616 dh.lockUpgradeFsm.RLock()
2617 defer dh.lockUpgradeFsm.RUnlock()
2618 if dh.pOnuUpradeFsm != nil {
2619 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2620 if pUpgradeStatemachine != nil {
2621 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2622 // (some manual forced commit could do without)
2623 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002624 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002625 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2626 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2627 return
2628 }
2629 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2630 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2631 } else {
2632 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2633 log.Fields{"device-id": dh.deviceID})
2634 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2635 return
2636 }
2637 }
2638 }
2639 } else {
2640 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2641 }
2642}
2643
Himani Chawla6d2ae152020-09-02 13:11:20 +05302644//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002645func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002646
2647 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002648 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002649 kvbackend := &db.Backend{
2650 Client: dh.pOpenOnuAc.kvClient,
2651 StoreType: dh.pOpenOnuAc.KVStoreType,
2652 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002653 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002654 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2655 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002656
mpagenkoaf801632020-07-03 10:00:42 +00002657 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002658}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002659func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302660 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002661
mpagenkodff5dda2020-08-28 11:52:01 +00002662 for _, field := range flow.GetOfbFields(apFlowItem) {
2663 switch field.Type {
2664 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2665 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002666 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002667 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2668 }
mpagenko01e726e2020-10-23 09:45:29 +00002669 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002670 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2671 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302672 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002673 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302674 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2675 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002676 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2677 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002678 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2679 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302680 return
mpagenkodff5dda2020-08-28 11:52:01 +00002681 }
2682 }
mpagenko01e726e2020-10-23 09:45:29 +00002683 */
mpagenkodff5dda2020-08-28 11:52:01 +00002684 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2685 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302686 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002687 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302688 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002689 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302690 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002691 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002692 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302693 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002694 }
2695 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2696 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302697 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002698 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002699 "PCP": loAddPcp})
2700 }
2701 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2702 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002703 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002704 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2705 }
2706 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2707 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002708 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002709 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2710 }
2711 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2712 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002714 "IPv4-DST": field.GetIpv4Dst()})
2715 }
2716 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2717 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002718 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002719 "IPv4-SRC": field.GetIpv4Src()})
2720 }
2721 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2722 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002723 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002724 "Metadata": field.GetTableMetadata()})
2725 }
2726 /*
2727 default:
2728 {
2729 //all other entires ignored
2730 }
2731 */
2732 }
2733 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302734}
mpagenkodff5dda2020-08-28 11:52:01 +00002735
dbainbri4d3a0dc2020-12-02 00:33:42 +00002736func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002737 for _, action := range flow.GetActions(apFlowItem) {
2738 switch action.Type {
2739 /* not used:
2740 case of.OfpActionType_OFPAT_OUTPUT:
2741 {
mpagenko01e726e2020-10-23 09:45:29 +00002742 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002743 "Output": action.GetOutput()})
2744 }
2745 */
2746 case of.OfpActionType_OFPAT_PUSH_VLAN:
2747 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002748 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002749 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2750 }
2751 case of.OfpActionType_OFPAT_SET_FIELD:
2752 {
2753 pActionSetField := action.GetSetField()
2754 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002755 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002756 "OxcmClass": pActionSetField.Field.OxmClass})
2757 }
2758 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302759 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002760 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302761 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002762 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302763 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002764 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302765 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002766 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002767 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002768 "Type": pActionSetField.Field.GetOfbField().Type})
2769 }
2770 }
2771 /*
2772 default:
2773 {
2774 //all other entires ignored
2775 }
2776 */
2777 }
2778 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302779}
2780
2781//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302783 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2784 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2785 var loAddPcp, loSetPcp uint8
2786 var loIPProto uint32
2787 /* the TechProfileId is part of the flow Metadata - compare also comment within
2788 * OLT-Adapter:openolt_flowmgr.go
2789 * Metadata 8 bytes:
2790 * Most Significant 2 Bytes = Inner VLAN
2791 * Next 2 Bytes = Tech Profile ID(TPID)
2792 * Least Significant 4 Bytes = Port ID
2793 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2794 * subscriber related flows.
2795 */
2796
dbainbri4d3a0dc2020-12-02 00:33:42 +00002797 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302798 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002799 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302800 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002801 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302802 }
mpagenko551a4d42020-12-08 18:09:20 +00002803 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002804 loCookie := apFlowItem.GetCookie()
2805 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002806 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002807 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302808
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002810 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302811 if loIPProto == 2 {
2812 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2813 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002814 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2815 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302816 return nil
2817 }
mpagenko01e726e2020-10-23 09:45:29 +00002818 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002820
2821 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002823 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2824 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2825 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2826 //TODO!!: Use DeviceId within the error response to rwCore
2827 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002828 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002829 }
2830 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002831 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002832 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2833 } else {
2834 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2835 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2836 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302837 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002838 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002840 }
mpagenko9a304ea2020-12-16 15:54:01 +00002841
2842 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002843 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002844 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302845 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002846 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002847 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002848 dh.lockVlanConfig.RUnlock()
2849 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002850 }
mpagenkof1fc3862021-02-16 10:09:52 +00002851 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002852 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002853 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002854}
2855
2856//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002857func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002858 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2859 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2860 //no extra check is done on the rule parameters
2861 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2862 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2863 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2864 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002865 // - 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 +00002866 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002867 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002868
2869 /* TT related temporary workaround - should not be needed anymore
2870 for _, field := range flow.GetOfbFields(apFlowItem) {
2871 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2872 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002873 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002874 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2875 if loIPProto == 2 {
2876 // 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 +00002877 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002878 log.Fields{"device-id": dh.deviceID})
2879 return nil
2880 }
2881 }
2882 } //for all OfbFields
2883 */
2884
mpagenko9a304ea2020-12-16 15:54:01 +00002885 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002886 dh.lockVlanConfig.RLock()
2887 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002888 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002890 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002891 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002892 log.Fields{"device-id": dh.deviceID})
2893 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002894 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002895 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002896
mpagenko01e726e2020-10-23 09:45:29 +00002897 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002898}
2899
Himani Chawla26e555c2020-08-31 12:30:20 +05302900// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002901// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002902func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002903 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002904 chVlanFilterFsm := make(chan Message, 2048)
2905
dbainbri4d3a0dc2020-12-02 00:33:42 +00002906 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002907 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002908 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302909 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002910 }
2911
dbainbri4d3a0dc2020-12-02 00:33:42 +00002912 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002913 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002914 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002915 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002916 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002917 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2918 // (from parallel processing)
2919 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302920 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002921 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2922 if pVlanFilterStatemachine != nil {
2923 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2924 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002925 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302926 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002927 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302928 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002929 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302930 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2931 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002932 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002934 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302935 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002936 }
2937 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002938 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002939 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302940 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002941 }
2942 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002943 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002944 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302945 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002946 }
2947 return nil
2948}
2949
mpagenkofc4f56e2020-11-04 17:17:49 +00002950//VerifyVlanConfigRequest checks on existence of a given uniPort
2951// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002952func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002953 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2954 var pCurrentUniPort *onuUniPort
2955 for _, uniPort := range dh.uniEntityMap {
2956 // only if this port is validated for operState transfer
2957 if uniPort.uniID == uint8(aUniID) {
2958 pCurrentUniPort = uniPort
2959 break //found - end search loop
2960 }
2961 }
2962 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002963 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002964 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2965 return
2966 }
mpagenko551a4d42020-12-08 18:09:20 +00002967 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002968}
2969
mpagenkodff5dda2020-08-28 11:52:01 +00002970//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002971func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002972 //TODO!! verify and start pending flow configuration
2973 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2974 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002975
2976 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302977 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002978 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002979 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2980 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2981 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002982 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2983 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2984 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2985 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2986 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2987 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2988 } else {
2989 /***** UniVlanConfigFsm continued */
2990 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2991 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2992 "UniPort": apUniPort.portNo})
2993 }
2994 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2995 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2996 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2997 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2998 } else {
2999 /***** UniVlanConfigFsm continued */
3000 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3001 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3002 "UniPort": apUniPort.portNo})
3003 }
mpagenkodff5dda2020-08-28 11:52:01 +00003004 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003005 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3006 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003007 "UniPort": apUniPort.portNo})
3008 }
3009 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003010 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3011 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3012 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003013 }
3014 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003015 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003016 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003017 }
mpagenkof1fc3862021-02-16 10:09:52 +00003018 } else {
3019 dh.lockVlanConfig.RUnlock()
3020 }
mpagenkodff5dda2020-08-28 11:52:01 +00003021}
3022
3023//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3024// 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 +00003025func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3026 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003027 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3028 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003029 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303030 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003031 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003032}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003033
mpagenkof1fc3862021-02-16 10:09:52 +00003034//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3035func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3036 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3037 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3038 // obviously then parallel processing on the cancel must be avoided
3039 // deadline context to ensure completion of background routines waited for
3040 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3041 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3042 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3043
3044 aPDevEntry.resetKvProcessingErrorIndication()
3045 var wg sync.WaitGroup
3046 wg.Add(1) // for the 1 go routine to finish
3047
3048 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3049 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3050
3051 return aPDevEntry.getKvProcessingErrorIndication()
3052}
3053
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003054//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3055//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003056func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3057 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003058
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003059 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003060 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003061 return nil
3062 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003063 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003064
dbainbri4d3a0dc2020-12-02 00:33:42 +00003065 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003066 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003067 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003068 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3069 }
3070 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3071
mpagenkof1fc3862021-02-16 10:09:52 +00003072 if aWriteToKvStore {
3073 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3074 }
3075 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003076}
3077
dbainbri4d3a0dc2020-12-02 00:33:42 +00003078func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003079 defer cancel() //ensure termination of context (may be pro forma)
3080 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003081 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003082 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003083}
3084
dbainbri4d3a0dc2020-12-02 00:33:42 +00003085func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003086
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003087 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003088 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003089 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003090 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3091 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003092 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003093 return err
3094 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003095 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003096 return nil
3097 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003098 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003099 return nil
3100}
3101
dbainbri4d3a0dc2020-12-02 00:33:42 +00003102func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3103 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003104 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003105 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003106 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3107 }
mpagenkof1fc3862021-02-16 10:09:52 +00003108 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003109}
3110
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003111func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3112 var errStr string = ""
3113 for _, err := range errS {
3114 if err != nil {
3115 errStr = errStr + err.Error() + " "
3116 }
3117 }
3118 if errStr != "" {
3119 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3120 }
3121 return nil
3122}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003123
3124// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
3125func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3126 dh.lockDevice.RLock()
3127 defer dh.lockDevice.RUnlock()
3128 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3129 return uniPort.entityID, nil
3130 }
3131 return 0, errors.New("error-fetching-uni-port")
3132}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003133
3134// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003135func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3136 var errorsList []error
3137 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 -08003138
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003139 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3140 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3141 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3142
3143 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3144 // successfully.
3145 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3146 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3147 if len(errorsList) > 0 {
3148 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3149 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003150 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003151 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3152 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003153}
3154
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003155func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3156 var err error
3157 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003158 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003159
3160 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3161 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3162 errorsList = append(errorsList, err)
3163 }
3164 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003165 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003166
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003167 return errorsList
3168}
3169
3170func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3171 var err error
3172 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003173 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003174 // Check if group metric related config is updated
3175 for _, v := range pmConfigs.Groups {
3176 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3177 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3178 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3179
3180 if ok && m.frequency != v.GroupFreq {
3181 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3182 errorsList = append(errorsList, err)
3183 }
3184 }
3185 if ok && m.enabled != v.Enabled {
3186 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3187 errorsList = append(errorsList, err)
3188 }
3189 }
3190 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003191 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003192 return errorsList
3193}
3194
3195func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3196 var err error
3197 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003198 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003199 // Check if standalone metric related config is updated
3200 for _, v := range pmConfigs.Metrics {
3201 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003202 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003203 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3204
3205 if ok && m.frequency != v.SampleFreq {
3206 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3207 errorsList = append(errorsList, err)
3208 }
3209 }
3210 if ok && m.enabled != v.Enabled {
3211 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3212 errorsList = append(errorsList, err)
3213 }
3214 }
3215 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003216 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003217 return errorsList
3218}
3219
3220// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003221func (dh *deviceHandler) startCollector(ctx context.Context) {
3222 logger.Debugf(ctx, "startingCollector")
3223
3224 // Start routine to process OMCI GET Responses
3225 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003226 // Initialize the next metric collection time.
3227 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3228 // reset like onu rebooted.
3229 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003230 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003231 for {
3232 select {
3233 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003234 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003235 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003236 // Stop the L2 PM FSM
3237 go func() {
3238 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3239 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3240 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3241 }
3242 } else {
3243 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3244 }
3245 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003246 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3247 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3248 }
3249 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3250 dh.pOnuMetricsMgr.stopTicks <- true
3251 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003252
Girish Gowdrae09a6202021-01-12 18:10:59 -08003253 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003254 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3255 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3256 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3257 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3258 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003259 // Update the next metric collection time.
3260 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003261 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003262 } else {
3263 if dh.pmConfigs.Grouped { // metrics are managed as a group
3264 // parse through the group and standalone metrics to see it is time to collect their metrics
3265 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003266
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003267 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3268 // 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 -08003269 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3270 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003271 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3272 }
3273 }
3274 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3275 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3276 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3277 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3278 }
3279 }
3280 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3281
3282 // parse through the group and update the next metric collection time
3283 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3284 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3285 // 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 -08003286 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3287 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003288 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3289 }
3290 }
3291 // parse through the standalone metrics and update the next metric collection time
3292 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3293 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3294 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3295 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3296 }
3297 }
3298 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3299 } /* else { // metrics are not managed as a group
3300 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3301 } */
3302 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003303 }
3304 }
3305}
kesavandfdf77632021-01-26 23:40:33 -05003306
3307func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3308
3309 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3310 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3311}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003312
mpagenkof1fc3862021-02-16 10:09:52 +00003313func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3314 if pFsm == nil {
3315 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003316 }
mpagenkof1fc3862021-02-16 10:09:52 +00003317 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003318}
3319
mpagenkof1fc3862021-02-16 10:09:52 +00003320func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3321 var pFsm *fsm.FSM
3322 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3323 switch omciFsm {
3324 case cUploadFsm:
3325 {
3326 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3327 }
3328 case cDownloadFsm:
3329 {
3330 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3331 }
3332 case cUniLockFsm:
3333 {
3334 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3335 }
3336 case cUniUnLockFsm:
3337 {
3338 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3339 }
3340 case cL2PmFsm:
3341 {
3342 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3343 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3344 } else {
3345 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003346 }
3347 }
mpagenko80622a52021-02-09 16:53:23 +00003348 case cOnuUpgradeFsm:
3349 {
3350 dh.lockUpgradeFsm.RLock()
3351 defer dh.lockUpgradeFsm.RUnlock()
3352 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3353 }
mpagenkof1fc3862021-02-16 10:09:52 +00003354 default:
3355 {
3356 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3357 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3358 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003359 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003360 }
mpagenkof1fc3862021-02-16 10:09:52 +00003361 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003362}
3363
mpagenkof1fc3862021-02-16 10:09:52 +00003364func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3365 for _, v := range dh.pOnuTP.pAniConfigFsm {
3366 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003367 return false
3368 }
3369 }
3370 return true
3371}
3372
mpagenkof1fc3862021-02-16 10:09:52 +00003373func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3374 dh.lockVlanConfig.RLock()
3375 defer dh.lockVlanConfig.RUnlock()
3376 for _, v := range dh.UniVlanConfigFsmMap {
3377 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3378 return false
3379 }
3380 }
3381 return true //FSM not active - so there is no activity on omci
3382}
3383
3384func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3385 dh.lockVlanConfig.RLock()
3386 defer dh.lockVlanConfig.RUnlock()
3387 for _, v := range dh.UniVlanConfigFsmMap {
3388 if v.pAdaptFsm.pFsm != nil {
3389 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3390 return true //there is at least one VLAN FSM with some active configuration
3391 }
3392 }
3393 }
3394 return false //there is no VLAN FSM with some active configuration
3395}
3396
3397func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3398 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3399 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3400 return false
3401 }
3402 }
3403 // a further check is done to identify, if at least some data traffic related configuration exists
3404 // 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])
3405 return dh.checkUserServiceExists(ctx)
3406}
3407
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003408func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3409 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3410 if err := dh.resetFsms(ctx, false); err != nil {
3411 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3412 // TODO: fatal error reset ONU, delete deviceHandler!
3413 return
3414 }
3415 if !dh.getCollectorIsRunning() {
3416 // Start PM collector routine
3417 go dh.startCollector(ctx)
3418 }
Himani Chawla1472c682021-03-17 17:11:14 +05303419 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303420 go dh.startAlarmManager(ctx)
3421 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003422 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003423 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003424}
3425
3426func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3427 dh.mutexCollectorFlag.Lock()
3428 dh.collectorIsRunning = flagValue
3429 dh.mutexCollectorFlag.Unlock()
3430}
3431
3432func (dh *deviceHandler) getCollectorIsRunning() bool {
3433 dh.mutexCollectorFlag.RLock()
3434 flagValue := dh.collectorIsRunning
3435 dh.mutexCollectorFlag.RUnlock()
3436 return flagValue
3437}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303438
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303439func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3440 dh.mutextAlarmManagerFlag.Lock()
3441 dh.alarmManagerIsRunning = flagValue
3442 dh.mutextAlarmManagerFlag.Unlock()
3443}
3444
Himani Chawla1472c682021-03-17 17:11:14 +05303445func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303446 dh.mutextAlarmManagerFlag.RLock()
3447 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303448 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303449 dh.mutextAlarmManagerFlag.RUnlock()
3450 return flagValue
3451}
3452
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303453func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3454 logger.Debugf(ctx, "startingAlarmManager")
3455
3456 // Start routine to process OMCI GET Responses
3457 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303458 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303459 if stop := <-dh.stopAlarmManager; stop {
3460 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303461 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303462 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303463 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3464 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3465 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303466 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303467 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303468 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3469 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303470 }
3471}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003472
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003473func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003474 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003475
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003476 if !dh.isReconciling() {
3477 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003478 logger.Debugw(ctx, "wait for channel signal or timeout",
3479 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003480 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003481 case success := <-dh.chReconcilingFinished:
3482 if success {
Maninderb5187552021-03-23 22:23:42 +05303483 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3484 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3485 log.Fields{"device-id": dh.deviceID})
3486 } else {
3487 connectStatus := voltha.ConnectStatus_UNREACHABLE
3488 operState := voltha.OperStatus_UNKNOWN
3489 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3490 connectStatus = voltha.ConnectStatus_REACHABLE
3491 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3492 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3493 operState = voltha.OperStatus_ACTIVE
3494 } else {
3495 operState = voltha.OperStatus_ACTIVATING
3496 }
3497 }
3498 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3499 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3500 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3501 operState = voltha.OperStatus_DISCOVERED
3502 }
3503
3504 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
3505 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3506 logger.Errorw(ctx, "unable to update device state to core",
3507 log.Fields{"OperState": onuDevEntry.sOnuPersistentData.PersOperState, "Err": err})
3508 }
3509 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003510 logger.Debugw(ctx, "reconciling has been finished in time",
3511 log.Fields{"device-id": dh.deviceID})
3512 } else {
Maninderb5187552021-03-23 22:23:42 +05303513 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003514 log.Fields{"device-id": dh.deviceID})
3515 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003516 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Maninderb5187552021-03-23 22:23:42 +05303517 //TODO: handle notification to core if reconciling timed out
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003518 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3519 log.Fields{"device-id": dh.deviceID})
3520 }
3521 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003522 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003523 dh.mutexReconcilingFlag.Unlock()
3524 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003525 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003526 dh.mutexReconcilingFlag.Lock()
3527 if skipOnuConfig {
3528 dh.reconciling = cSkipOnuConfigReconciling
3529 } else {
3530 dh.reconciling = cOnuConfigReconciling
3531 }
3532 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003533}
3534
3535func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3536 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3537 if dh.isReconciling() {
3538 dh.chReconcilingFinished <- true
3539 } else {
3540 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3541 }
3542}
3543
3544func (dh *deviceHandler) isReconciling() bool {
3545 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003546 defer dh.mutexReconcilingFlag.RUnlock()
3547 return dh.reconciling != cNoReconciling
3548}
3549
3550func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3551 dh.mutexReconcilingFlag.RLock()
3552 defer dh.mutexReconcilingFlag.RUnlock()
3553 return dh.reconciling == cSkipOnuConfigReconciling
3554}
3555
3556func (dh *deviceHandler) setDeviceReason(value uint8) {
3557 dh.mutexDeviceReason.Lock()
3558 dh.deviceReason = value
3559 dh.mutexDeviceReason.Unlock()
3560}
3561
3562func (dh *deviceHandler) getDeviceReason() uint8 {
3563 dh.mutexDeviceReason.RLock()
3564 value := dh.deviceReason
3565 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003566 return value
3567}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003568
3569func (dh *deviceHandler) getDeviceReasonString() string {
3570 return deviceReasonMap[dh.getDeviceReason()]
3571}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003572
3573func (dh *deviceHandler) setReconcilingFlows(value bool) {
3574 dh.mutexReconcilingFlowsFlag.Lock()
3575 dh.reconcilingFlows = value
3576 dh.mutexReconcilingFlowsFlag.Unlock()
3577}
3578
3579func (dh *deviceHandler) isReconcilingFlows() bool {
3580 dh.mutexReconcilingFlowsFlag.RLock()
3581 value := dh.reconcilingFlows
3582 dh.mutexReconcilingFlowsFlag.RUnlock()
3583 return value
3584}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003585
3586func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3587 dh.mutexReadyForOmciConfig.Lock()
3588 dh.readyForOmciConfig = flagValue
3589 dh.mutexReadyForOmciConfig.Unlock()
3590}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003591func (dh *deviceHandler) isReadyForOmciConfig() bool {
3592 dh.mutexReadyForOmciConfig.RLock()
3593 flagValue := dh.readyForOmciConfig
3594 dh.mutexReadyForOmciConfig.RUnlock()
3595 return flagValue
3596}