blob: fe64bf2a1748edf2b3e3e0a809b3c559fe89966a [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 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700411 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412
dbainbri4d3a0dc2020-12-02 00:33:42 +0000413 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700414 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 // if there has been some change for some uni TechProfilePath
416 //in order to allow concurrent calls to other dh instances we do not wait for execution here
417 //but doing so we can not indicate problems to the caller (who does what with that then?)
418 //by now we just assume straightforward successful execution
419 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
420 // possible problems to the caller later autonomously
421
422 // deadline context to ensure completion of background routines waited for
423 //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 +0530424 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 dctx, cancel := context.WithDeadline(context.Background(), deadline)
426
Girish Gowdra041dcb32020-11-16 16:54:30 -0800427 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000428
Himani Chawla26e555c2020-08-31 12:30:20 +0530429 var wg sync.WaitGroup
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700430 wg.Add(1) // for the 1 go routine to finish
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700434 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
435 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.Path})
436 return tpErr
437 }
438 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
439 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
440 pDevEntry.resetKvProcessingErrorIndication()
441 wg.Add(1) // for the 1 go routine to finish
442 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
443 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
444 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
445 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.Path})
446 return kvErr
447 }
448 return nil
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450 // no change, nothing really to do - return success
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700451 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 return nil
453}
454
Himani Chawla6d2ae152020-09-02 13:11:20 +0530455func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000456 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530457 msg *ic.InterAdapterMessage) error {
458
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000460
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000462 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000464 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
465 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530466 if dh.pOnuTP == nil {
467 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000468 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530471 }
472
473 msgBody := msg.GetBody()
474 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
475 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 "device-id": dh.deviceID, "error": err})
478 return err
479 }
480
481 //compare TECH_PROFILE_DOWNLOAD_REQUEST
482 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530484
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 if delGemPortMsg.UniId > 255 {
486 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
487 delGemPortMsg.UniId, dh.deviceID))
488 }
489 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800490 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
491 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 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 -0800493 return err
494 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530495
mpagenkofc4f56e2020-11-04 17:17:49 +0000496 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497
mpagenkofc4f56e2020-11-04 17:17:49 +0000498 // deadline context to ensure completion of background routines waited for
499 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
500 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501
Girish Gowdra041dcb32020-11-16 16:54:30 -0800502 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503
mpagenkofc4f56e2020-11-04 17:17:49 +0000504 var wg sync.WaitGroup
505 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000507 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000509
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530511}
512
Himani Chawla6d2ae152020-09-02 13:11:20 +0530513func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
dbainbri4d3a0dc2020-12-02 00:33:42 +0000517 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000518
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
523 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 if dh.pOnuTP == nil {
525 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530527 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
530
531 msgBody := msg.GetBody()
532 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
533 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 "device-id": dh.deviceID, "error": err})
536 return err
537 }
538
539 //compare TECH_PROFILE_DOWNLOAD_REQUEST
540 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000542
543 if delTcontMsg.UniId > 255 {
544 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
545 delTcontMsg.UniId, dh.deviceID))
546 }
547 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800548 tpPath := delTcontMsg.TpPath
549 tpID, err := GetTpIDFromTpPath(tpPath)
550 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800552 return err
553 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000554
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700556 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530557 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530558 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530559 dctx, cancel := context.WithDeadline(context.Background(), deadline)
560
Girish Gowdra041dcb32020-11-16 16:54:30 -0800561 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000562 pDevEntry.resetKvProcessingErrorIndication()
563
Himani Chawla26e555c2020-08-31 12:30:20 +0530564 var wg sync.WaitGroup
565 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000566 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530567 cResourceTcont, delTcontMsg.AllocId, &wg)
568 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
570 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571
Girish Gowdra041dcb32020-11-16 16:54:30 -0800572 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530573 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 return nil
575}
576
Himani Chawla6d2ae152020-09-02 13:11:20 +0530577//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000578// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
579// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000581 msgID := msg.Header.Id
582 msgType := msg.Header.Type
583 fromTopic := msg.Header.FromTopic
584 toTopic := msg.Header.ToTopic
585 toDeviceID := msg.Header.ToDeviceId
586 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000588 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
589
590 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000591 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000592 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
593 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000594 {
mpagenko057889c2021-01-21 16:51:58 +0000595 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000596 }
mpagenkoaf801632020-07-03 10:00:42 +0000597 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
598 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000600 }
601 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
602 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000604
mpagenkoaf801632020-07-03 10:00:42 +0000605 }
606 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
607 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000609 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000610 default:
611 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000613 "msgType": msg.Header.Type, "device-id": dh.deviceID})
614 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000615 }
616 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000617}
618
mpagenkodff5dda2020-08-28 11:52:01 +0000619//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
621 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000622 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000624
mpagenko01e726e2020-10-23 09:45:29 +0000625 var retError error = nil
626 //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 +0000627 if apOfFlowChanges.ToRemove != nil {
628 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000629 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000631 "device-id": dh.deviceID})
632 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000633 continue
634 }
635 flowInPort := flow.GetInPort(flowItem)
636 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 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 +0000638 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
639 continue
640 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000641 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000642 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000644 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000645 continue
646 } else {
647 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530648 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000649 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
650 loUniPort = uniPort
651 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000653 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
654 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
655 flowInPort, dh.deviceID)
656 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000657 }
658 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000660 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000661 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000663 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000664 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000666 log.Fields{"device-id": dh.deviceID, "error": err})
667 retError = err
668 continue
669 //return err
670 } else { // if last setting succeeds, overwrite possibly previously set error
671 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000672 }
673 }
674 }
675 }
mpagenko01e726e2020-10-23 09:45:29 +0000676 if apOfFlowChanges.ToAdd != nil {
677 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
678 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000680 "device-id": dh.deviceID})
681 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
682 continue
683 }
684 flowInPort := flow.GetInPort(flowItem)
685 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 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 +0000687 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
688 continue
689 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
690 } else if flowInPort == dh.ponPortNumber {
691 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000693 "device-id": dh.deviceID, "inPort": flowInPort})
694 continue
695 } else {
696 // this is the relevant upstream flow
697 var loUniPort *onuUniPort
698 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
699 loUniPort = uniPort
700 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000702 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
703 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
704 flowInPort, dh.deviceID)
705 continue
706 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
707 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000708 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
709 // if not, we just throw some error here to have an indication about that, if we really need to support that
710 // then we would need to create some means to activate the internal stored flows
711 // after the device gets active automatically (and still with its dependency to the TechProfile)
712 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
713 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000714 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000716 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000717 return fmt.Errorf("improper device state on device %s", dh.deviceID)
718 }
719
mpagenko01e726e2020-10-23 09:45:29 +0000720 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000722 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
723 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000725 //try next flow after processing error
726 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000728 log.Fields{"device-id": dh.deviceID, "error": err})
729 retError = err
730 continue
731 //return err
732 } else { // if last setting succeeds, overwrite possibly previously set error
733 retError = nil
734 }
735 }
736 }
737 }
738 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000739}
740
Himani Chawla6d2ae152020-09-02 13:11:20 +0530741//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000742//following are the expected device states after this activity:
743//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
744// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
746 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000747
mpagenko900ee4b2020-10-12 11:56:34 +0000748 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 //note that disableDevice sequences in some 'ONU active' state may yield also
750 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000751 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000752 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000753 //disable-device shall be just a UNi/ONU-G related admin state setting
754 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000755
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000756 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000757 // disable UNI ports/ONU
758 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
759 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000761 } else { //LockStateFSM already init
762 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000764 }
765 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000767 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000769 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
770 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000772 }
mpagenko01e726e2020-10-23 09:45:29 +0000773 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000774
775 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000777 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300778 }
779}
780
Himani Chawla6d2ae152020-09-02 13:11:20 +0530781//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
783 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000784
mpagenkoaa3afe92021-05-21 16:20:58 +0000785 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000786 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
787 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
788 // for real ONU's that should have nearly no influence
789 // Note that for real ONU's there is anyway a problematic situation with following sequence:
790 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
791 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
792 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000793 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000794
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000795 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000796 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000797 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000799 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000800 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000802 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300803}
804
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
806 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000807
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000811 return
812 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000814 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000816 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000818 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000819 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000820 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000821 }
Himani Chawla4d908332020-08-31 12:30:20 +0530822 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000823 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000824 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
825 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
826 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
827 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000828 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000830}
831
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
833 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000834
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000838 if !dh.isSkipOnuConfigReconciling() {
839 dh.stopReconciling(ctx)
840 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000841 return
842 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843 dh.pOnuTP.lockTpProcMutex()
844 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000845 pDevEntry.mutexPersOnuConfig.RLock()
846 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000847
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000848 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000850 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000851 if !dh.isSkipOnuConfigReconciling() {
852 dh.stopReconciling(ctx)
853 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 return
855 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000856 techProfsFound := false
857 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000858 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000859 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
860 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000861 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000862 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000863 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000865 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800866 for tpID := range uniData.PersTpPathMap {
867 // deadline context to ensure completion of background routines waited for
868 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
869 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000871
Girish Gowdra041dcb32020-11-16 16:54:30 -0800872 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
873 var wg sync.WaitGroup
874 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
876 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800877 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800879 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000880 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000881 if len(uniData.PersFlowParams) != 0 {
882 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000885 if !techProfsFound {
886 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
887 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000888 if !dh.isSkipOnuConfigReconciling() {
889 dh.stopReconciling(ctx)
890 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000891 return
892 }
893 if dh.isSkipOnuConfigReconciling() {
894 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
895 }
896 if !flowsFound {
897 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
898 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000899 if !dh.isSkipOnuConfigReconciling() {
900 dh.stopReconciling(ctx)
901 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000902 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903}
904
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
906 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000907
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000911 if !dh.isSkipOnuConfigReconciling() {
912 dh.stopReconciling(ctx)
913 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000914 return
915 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000916 pDevEntry.mutexPersOnuConfig.RLock()
917 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000919 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000920 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000921 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000922 if !dh.isSkipOnuConfigReconciling() {
923 dh.stopReconciling(ctx)
924 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000925 return
926 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000927 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000928 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000929 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
930 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000932 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000933 continue
934 }
935 if len(uniData.PersTpPathMap) == 0 {
936 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
937 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000938 // It doesn't make sense to configure any flows if no TPs are available
939 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000940 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000941 var uniPort *onuUniPort
942 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000944 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000945 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
946 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000947 if !dh.isSkipOnuConfigReconciling() {
948 dh.stopReconciling(ctx)
949 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950 return
951 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000952 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200953 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000954 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000955 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000957 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 +0200958 // If this is the last flow for the device we need to announce it the waiting
959 // chReconcilingFlowsFinished channel
960 if flowsProcessed == len(uniData.PersFlowParams)-1 {
961 lastFlowToReconcile = true
962 }
mpagenko01e726e2020-10-23 09:45:29 +0000963 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000964 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000965 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000967 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200968 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000970 }
mpagenkof1fc3862021-02-16 10:09:52 +0000971 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000972 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000973 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000975 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200976 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000978 }
979 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000981 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
983 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
984 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200985 // this can't be used as global finished reconciling flag because
986 // assumes is getting called before the state machines for the last flow is completed,
987 // while this is not guaranteed.
988 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000989 }
990 if !flowsFound {
991 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
992 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000993 if !dh.isSkipOnuConfigReconciling() {
994 dh.stopReconciling(ctx)
995 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000996 return
997 }
998 if dh.isSkipOnuConfigReconciling() {
999 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001000 }
1001}
1002
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001003func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1004 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001005 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001006}
1007
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1009 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001010
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001013 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001015 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001016 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017
1018 // deadline context to ensure completion of background routines waited for
1019 //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 +05301020 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001022
1023 pDevEntry.resetKvProcessingErrorIndication()
1024
1025 var wg sync.WaitGroup
1026 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1028 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001029
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001030 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001031 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001032}
1033
mpagenko15ff4a52021-03-02 10:09:20 +00001034//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1035// before this change here return like this was used:
1036// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1037//was and is called in background - error return does not make sense
1038func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1039 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1040 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001041 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001042 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001043 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301045 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001047 return
Himani Chawla4d908332020-08-31 12:30:20 +05301048 }
mpagenko01e726e2020-10-23 09:45:29 +00001049
1050 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001052
dbainbri4d3a0dc2020-12-02 00:33:42 +00001053 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001054 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001056 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001057 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001059 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001060 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001062 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001063 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001064 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001065 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1066 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1067 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1068 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001069}
1070
mpagenkoc8bba412021-01-15 15:38:44 +00001071//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001072func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1073 apDownloadManager *adapterDownloadManager) error {
1074 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001075 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001076
1077 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001078 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1079 if pDevEntry == nil {
1080 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1081 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1082 }
1083
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001084 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001085 var inactiveImageID uint16
1086 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1087 dh.lockUpgradeFsm.Lock()
1088 defer dh.lockUpgradeFsm.Unlock()
1089 if dh.pOnuUpradeFsm == nil {
1090 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1091 if err == nil {
1092 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1093 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1094 "device-id": dh.deviceID, "error": err})
1095 }
1096 } else {
1097 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001098 "device-id": dh.deviceID, "error": err})
1099 }
mpagenko15ff4a52021-03-02 10:09:20 +00001100 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1101 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1102 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1103 if pUpgradeStatemachine != nil {
1104 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1105 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1106 "device-id": dh.deviceID, "error": err})
1107 }
1108 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1109 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1110 // for now a second start of download should work again
1111 } else { //should never occur
1112 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1113 "device-id": dh.deviceID})
1114 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001115 }
mpagenko80622a52021-02-09 16:53:23 +00001116 }
mpagenko15ff4a52021-03-02 10:09:20 +00001117 } else {
1118 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1119 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001120 }
1121 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001122 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1123 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001124 }
1125 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001126}
1127
mpagenkoc26d4c02021-05-06 14:27:57 +00001128//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1129// after the OnuImage has been downloaded to the adapter, called in background
1130func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1131 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1132
1133 var err error
1134 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1135 if pDevEntry == nil {
1136 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1137 return
1138 }
1139
1140 var inactiveImageID uint16
1141 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1142 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1143 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1144 dh.lockUpgradeFsm.Lock()
1145 defer dh.lockUpgradeFsm.Unlock()
1146 if dh.pOnuUpradeFsm == nil {
1147 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1148 // but none yet defined
1149 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1150 if err == nil {
1151 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001152 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001153 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1154 "device-id": dh.deviceID, "error": err})
1155 return
1156 }
1157 } else {
1158 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1159 "device-id": dh.deviceID, "error": err})
1160 }
1161 return
1162 }
1163 //OnuSw upgrade already running - restart (with possible abort of running)
1164 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1165 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1166 if pUpgradeStatemachine != nil {
1167 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1168 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1169 "device-id": dh.deviceID, "error": err})
1170 return
1171 }
1172 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1173 // for now a second start of download should work again - must still be initiated by user
1174 } else { //should never occur
1175 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1176 "device-id": dh.deviceID})
1177 }
1178 return
1179 }
1180 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1181 "device-id": dh.deviceID, "error": err})
1182}
1183
1184//onuSwActivateRequest ensures activation of the requested image with commit options
1185func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context, aVersion string, aCommitRequest bool) {
1186 var err error
1187 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1188 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1189 // 2.) activation of the inactive image
1190
1191 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1192 if pDevEntry == nil {
1193 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1194 return
1195 }
1196 dh.lockUpgradeFsm.RLock()
1197 if dh.pOnuUpradeFsm != nil {
1198 dh.lockUpgradeFsm.RUnlock()
1199 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1200 dh.deviceID, dh.deviceID)
1201 if getErr != nil || onuVolthaDevice == nil {
1202 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
1203 return
1204 }
1205 // use the OnuVendor identification from this device for the internal unique name
1206 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1207 // 1.) check a started upgrade process and rely the activation request to it
1208 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
1209 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1210 "device-id": dh.deviceID, "error": err})
1211 } else {
1212 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1213 "device-id": dh.deviceID, "image-id": imageIdentifier})
1214 }
1215 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
1216 // (even though parameter setting is not accepted)
1217 return
1218 } //else
1219 dh.lockUpgradeFsm.RUnlock()
1220
1221 // 2.) check if requested image-version equals the inactive one and start its activation
1222 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1223 var inactiveImageID uint16
1224 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1225 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1226 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
1227 return
1228 }
1229 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1230 if err == nil {
1231 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1232 inactiveImageID, aCommitRequest); err != nil {
1233 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1234 "device-id": dh.deviceID, "error": err})
1235 return
1236 }
1237 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1238 "device-id": dh.deviceID, "image-version": aVersion})
1239 return
1240 } //else
1241 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1242 "device-id": dh.deviceID, "error": err})
1243}
1244
1245//onuSwCommitRequest ensures commitment of the requested image
1246func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context, aVersion string) {
1247 var err error
1248 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1249 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1250 // 2.) commitment of the active image
1251
1252 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1253 if pDevEntry == nil {
1254 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1255 return
1256 }
1257 dh.lockUpgradeFsm.RLock()
1258 if dh.pOnuUpradeFsm != nil {
1259 dh.lockUpgradeFsm.RUnlock()
1260 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1261 dh.deviceID, dh.deviceID)
1262 if getErr != nil || onuVolthaDevice == nil {
1263 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
1264 return
1265 }
1266 // use the OnuVendor identification from this device for the internal unique name
1267 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1268 // 1.) check a started upgrade process and rely the commitment request to it
1269 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
1270 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1271 "device-id": dh.deviceID, "error": err})
1272 } else {
1273 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1274 "device-id": dh.deviceID, "image-id": imageIdentifier})
1275 }
1276 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
1277 // (even though parameter setting is not accepted)
1278 return
1279 } //else
1280 dh.lockUpgradeFsm.RUnlock()
1281
1282 // 2.) check if requested image-version equals the inactive one and start its commitment
1283 var activeImageID uint16
1284 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1285 logger.Errorw(ctx, "get active image failed", log.Fields{
1286 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
1287 return
1288 }
1289 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1290 if err == nil {
1291 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1292 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1293 "device-id": dh.deviceID, "error": err})
1294 return
1295 }
1296 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1297 "device-id": dh.deviceID, "image-version": aVersion})
1298 return
1299 } //else
1300 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1301 "device-id": dh.deviceID, "error": err})
1302}
1303
mpagenkoaa3afe92021-05-21 16:20:58 +00001304func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1305 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1306 pDeviceImageState.DeviceId = dh.deviceID
1307 pDeviceImageState.ImageState.Version = aImageIdentifier
1308 dh.lockUpgradeFsm.RLock()
1309 if dh.pOnuUpradeFsm != nil {
1310 dh.lockUpgradeFsm.RUnlock()
1311 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err != nil {
1312 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1313 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1314 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1315 } else {
1316 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1317 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1318 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1319 }
1320 } else {
1321 dh.lockUpgradeFsm.RUnlock()
1322 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1323 if dh.upgradeSuccess {
1324 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1325 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1326 } else {
1327 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1328 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1329 }
1330 }
1331}
1332
1333func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1334 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1335 pDeviceImageState.DeviceId = dh.deviceID
1336 pDeviceImageState.ImageState.Version = aImageIdentifier
1337 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1338 dh.lockUpgradeFsm.RLock()
1339 if dh.pOnuUpradeFsm != nil {
1340 dh.lockUpgradeFsm.RUnlock()
1341 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1342 // by now just straightforward assume this to be true
1343 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1344 //nolint:misspell
1345 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1346 //nolint:misspell
1347 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1348 } else {
1349 dh.lockUpgradeFsm.RUnlock()
1350 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1351 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1352 }
1353}
1354
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001355func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1356
1357 var onuImageStatus *OnuImageStatus
1358
1359 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1360 if pDevEntry != nil {
1361 onuImageStatus = NewOnuImageStatus(pDevEntry)
1362 pDevEntry.mutexOnuImageStatus.Lock()
1363 pDevEntry.pOnuImageStatus = onuImageStatus
1364 pDevEntry.mutexOnuImageStatus.Unlock()
1365
1366 } else {
1367 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1368 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1369 }
1370 images, err := onuImageStatus.getOnuImageStatus(ctx)
1371 pDevEntry.mutexOnuImageStatus.Lock()
1372 pDevEntry.pOnuImageStatus = nil
1373 pDevEntry.mutexOnuImageStatus.Unlock()
1374 return images, err
1375}
1376
Himani Chawla6d2ae152020-09-02 13:11:20 +05301377// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001378// #####################################################################################
1379
1380// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301381// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001382
dbainbri4d3a0dc2020-12-02 00:33:42 +00001383func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1384 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 +00001385}
1386
1387// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001388func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001389
dbainbri4d3a0dc2020-12-02 00:33:42 +00001390 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001391 var err error
1392
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001393 // populate what we know. rest comes later after mib sync
1394 dh.device.Root = false
1395 dh.device.Vendor = "OpenONU"
1396 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001397 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001398 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001399
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001400 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001401
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001402 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001403 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1404 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301405 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001406 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001408 log.Fields{"device-id": dh.deviceID})
1409 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001410
Himani Chawla4d908332020-08-31 12:30:20 +05301411 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001412 dh.ponPortNumber = dh.device.ParentPortNo
1413
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001414 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1415 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1416 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001417 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001418 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301419 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001420
1421 /*
1422 self._pon = PonPort.create(self, self._pon_port_number)
1423 self._pon.add_peer(self.parent_id, self._pon_port_number)
1424 self.logger.debug('adding-pon-port-to-agent',
1425 type=self._pon.get_port().type,
1426 admin_state=self._pon.get_port().admin_state,
1427 oper_status=self._pon.get_port().oper_status,
1428 )
1429 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001430 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001432 var ponPortNo uint32 = 1
1433 if dh.ponPortNumber != 0 {
1434 ponPortNo = dh.ponPortNumber
1435 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001436
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001437 pPonPort := &voltha.Port{
1438 PortNo: ponPortNo,
1439 Label: fmt.Sprintf("pon-%d", ponPortNo),
1440 Type: voltha.Port_PON_ONU,
1441 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301442 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001443 PortNo: ponPortNo}}, // Peer port is parent's port number
1444 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1446 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001447 e.Cancel(err)
1448 return
1449 }
1450 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001453 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454}
1455
1456// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001458
dbainbri4d3a0dc2020-12-02 00:33:42 +00001459 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001460 var err error
1461 /*
1462 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1463 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1464 return nil
1465 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001466 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1467 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001468 e.Cancel(err)
1469 return
1470 }
1471
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001472 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001473 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001474 // reconcilement will be continued after mib download is done
1475 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001476
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001477 /*
1478 ############################################################################
1479 # Setup Alarm handler
1480 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1481 device.serial_number)
1482 ############################################################################
1483 # Setup PM configuration for this device
1484 # Pass in ONU specific options
1485 kwargs = {
1486 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1487 'heartbeat': self.heartbeat,
1488 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1489 }
1490 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1491 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1492 self.logical_device_id, device.serial_number,
1493 grouped=True, freq_override=False, **kwargs)
1494 pm_config = self._pm_metrics.make_proto()
1495 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1496 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1497 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1498
1499 # Note, ONU ID and UNI intf set in add_uni_port method
1500 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1501 ani_ports=[self._pon])
1502
1503 # Code to Run OMCI Test Action
1504 kwargs_omci_test_action = {
1505 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1506 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1507 }
1508 serial_number = device.serial_number
1509 self._test_request = OmciTestRequest(self.core_proxy,
1510 self.omci_agent, self.device_id,
1511 AniG, serial_number,
1512 self.logical_device_id,
1513 exclusive=False,
1514 **kwargs_omci_test_action)
1515
1516 self.enabled = True
1517 else:
1518 self.logger.info('onu-already-activated')
1519 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001520
dbainbri4d3a0dc2020-12-02 00:33:42 +00001521 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001522}
1523
1524// doStateConnected get the device info and update to voltha core
1525// for comparison of the original method (not that easy to uncomment): compare here:
1526// voltha-openolt-adapter/adaptercore/device_handler.go
1527// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001528func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001529
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301531 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001532 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001534}
1535
1536// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001538
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301540 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001541 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001543
1544 /*
1545 // Synchronous call to update device state - this method is run in its own go routine
1546 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1547 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001548 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 +00001549 return err
1550 }
1551 return nil
1552 */
1553}
1554
1555// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001557
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559 var err error
1560
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001561 device := dh.device
1562 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001563 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001564 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001565 e.Cancel(err)
1566 return
1567 }
1568
1569 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001571 /*
1572 // Update the all ports state on that device to disable
1573 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001574 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001575 return er
1576 }
1577
1578 //Update the device oper state and connection status
1579 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1580 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1581 dh.device = cloned
1582
1583 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001584 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001585 return er
1586 }
1587
1588 //get the child device for the parent device
1589 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1590 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001591 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001592 return err
1593 }
1594 for _, onuDevice := range onuDevices.Items {
1595
1596 // Update onu state as down in onu adapter
1597 onuInd := oop.OnuIndication{}
1598 onuInd.OperState = "down"
1599 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1600 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1601 if er != nil {
1602 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001603 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001604 //Do not return here and continue to process other ONUs
1605 }
1606 }
1607 // * Discovered ONUs entries need to be cleared , since after OLT
1608 // is up, it starts sending discovery indications again* /
1609 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001610 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001611 return nil
1612 */
Himani Chawla4d908332020-08-31 12:30:20 +05301613 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001614 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001616}
1617
Himani Chawla6d2ae152020-09-02 13:11:20 +05301618// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001619// #################################################################################
1620
1621// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301622// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001623
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001624//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001626 dh.lockDevice.RLock()
1627 pOnuDeviceEntry := dh.pOnuOmciDevice
1628 if aWait && pOnuDeviceEntry == nil {
1629 //keep the read sema short to allow for subsequent write
1630 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001632 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1633 // so it might be needed to wait here for that event with some timeout
1634 select {
1635 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001637 return nil
1638 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001640 // if written now, we can return the written value without sema
1641 return dh.pOnuOmciDevice
1642 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643 }
mpagenko3af1f032020-06-10 08:53:41 +00001644 dh.lockDevice.RUnlock()
1645 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646}
1647
Himani Chawla6d2ae152020-09-02 13:11:20 +05301648//setOnuDeviceEntry sets the ONU device entry within the handler
1649func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001650 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001651 dh.lockDevice.Lock()
1652 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001653 dh.pOnuOmciDevice = apDeviceEntry
1654 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001655 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301656 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001657 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658}
1659
Himani Chawla6d2ae152020-09-02 13:11:20 +05301660//addOnuDeviceEntry creates a new ONU device or returns the existing
1661func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001663
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665 if deviceEntry == nil {
1666 /* costum_me_map in python code seems always to be None,
1667 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1668 /* also no 'clock' argument - usage open ...*/
1669 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001670 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001671 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001672 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301673 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001674 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001676 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001677 // fire deviceEntry ready event to spread to possibly waiting processing
1678 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001682 }
1683 // might be updated with some error handling !!!
1684 return nil
1685}
1686
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1688 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001689 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1690
1691 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001696 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1697 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001698 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001699 if err := dh.storePersistentData(ctx); err != nil {
1700 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001701 log.Fields{"device-id": dh.deviceID, "err": err})
1702 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001704 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001706 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1707 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001709 }
1710 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001711 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001712 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001713
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001714 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001715 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001716 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 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 +00001718 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001719 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001720 } else {
1721 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001722 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001724 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1725 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1726 // 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 +00001727 // 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 +00001728 // so let's just try to keep it simple ...
1729 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001731 if err != nil || device == nil {
1732 //TODO: needs to handle error scenarios
1733 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1734 return errors.New("Voltha Device not found")
1735 }
1736 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001737
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001739 return err
mpagenko3af1f032020-06-10 08:53:41 +00001740 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001741
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001742 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001743
1744 /* this might be a good time for Omci Verify message? */
1745 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001747 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001748 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001750
1751 /* give the handler some time here to wait for the OMCi verification result
1752 after Timeout start and try MibUpload FSM anyway
1753 (to prevent stopping on just not supported OMCI verification from ONU) */
1754 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001755 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001757 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759 }
1760
1761 /* In py code it looks earlier (on activate ..)
1762 # Code to Run OMCI Test Action
1763 kwargs_omci_test_action = {
1764 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1765 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1766 }
1767 serial_number = device.serial_number
1768 self._test_request = OmciTestRequest(self.core_proxy,
1769 self.omci_agent, self.device_id,
1770 AniG, serial_number,
1771 self.logical_device_id,
1772 exclusive=False,
1773 **kwargs_omci_test_action)
1774 ...
1775 # Start test requests after a brief pause
1776 if not self._test_request_started:
1777 self._test_request_started = True
1778 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1779 reactor.callLater(tststart, self._test_request.start_collector)
1780
1781 */
1782 /* which is then: in omci_test_request.py : */
1783 /*
1784 def start_collector(self, callback=None):
1785 """
1786 Start the collection loop for an adapter if the frequency > 0
1787
1788 :param callback: (callable) Function to call to collect PM data
1789 """
1790 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1791 if callback is None:
1792 callback = self.perform_test_omci
1793
1794 if self.lc is None:
1795 self.lc = LoopingCall(callback)
1796
1797 if self.default_freq > 0:
1798 self.lc.start(interval=self.default_freq / 10)
1799
1800 def perform_test_omci(self):
1801 """
1802 Perform the initial test request
1803 """
1804 ani_g_entities = self._device.configuration.ani_g_entities
1805 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1806 is not None else None
1807 self._entity_id = ani_g_entities_ids[0]
1808 self.logger.info('perform-test', entity_class=self._entity_class,
1809 entity_id=self._entity_id)
1810 try:
1811 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1812 result = yield self._device.omci_cc.send(frame)
1813 if not result.fields['omci_message'].fields['success_code']:
1814 self.logger.info('Self-Test Submitted Successfully',
1815 code=result.fields[
1816 'omci_message'].fields['success_code'])
1817 else:
1818 raise TestFailure('Test Failure: {}'.format(
1819 result.fields['omci_message'].fields['success_code']))
1820 except TimeoutError as e:
1821 self.deferred.errback(failure.Failure(e))
1822
1823 except Exception as e:
1824 self.logger.exception('perform-test-Error', e=e,
1825 class_id=self._entity_class,
1826 entity_id=self._entity_id)
1827 self.deferred.errback(failure.Failure(e))
1828
1829 */
1830
1831 // PM related heartbeat??? !!!TODO....
1832 //self._heartbeat.enabled = True
1833
mpagenko1cc3cb42020-07-27 15:24:38 +00001834 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1835 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1836 * 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 +05301837 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001838 */
1839 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001840 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001841 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001842 if pMibUlFsm.Is(ulStDisabled) {
1843 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 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 +00001845 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301846 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301848 //Determine ONU status and start/re-start MIB Synchronization tasks
1849 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001850 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301851 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001852 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 +00001853 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001854 }
Himani Chawla4d908332020-08-31 12:30:20 +05301855 } else {
1856 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857 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 +00001858 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301859 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001861 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001862 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001864 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001865 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001866 }
1867 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001869 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001870 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001871
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001872 if !dh.getCollectorIsRunning() {
1873 // Start PM collector routine
1874 go dh.startCollector(ctx)
1875 }
Himani Chawla1472c682021-03-17 17:11:14 +05301876 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301877 go dh.startAlarmManager(ctx)
1878 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301879
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880 return nil
1881}
1882
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001884 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001885 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001886 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001888
mpagenko900ee4b2020-10-12 11:56:34 +00001889 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1890 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1891 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001892 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001894 log.Fields{"device-id": dh.deviceID, "error": err})
1895 // abort: system behavior is just unstable ...
1896 return err
1897 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001898 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 _ = 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 +00001900
1901 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1902 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1903 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001905 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001907 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001908 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001909 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001910
1911 //TODO!!! remove existing traffic profiles
1912 /* from py code, if TP's exist, remove them - not yet implemented
1913 self._tp = dict()
1914 # Let TP download happen again
1915 for uni_id in self._tp_service_specific_task:
1916 self._tp_service_specific_task[uni_id].clear()
1917 for uni_id in self._tech_profile_download_done:
1918 self._tech_profile_download_done[uni_id].clear()
1919 */
1920
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001922
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001923 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001924
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001926 // abort: system behavior is just unstable ...
1927 return err
1928 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001930 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001932 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001933 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001935 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001936 // abort: system behavior is just unstable ...
1937 return err
1938 }
1939 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001941 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001942 return nil
1943}
1944
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001945func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001946 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1947 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1948 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1949 // and using the stop/reset event should never harm
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001952 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001954 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1955 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001956 if pDevEntry.PDevOmciCC != nil {
1957 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1958 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001959 pDevEntry.mutexOnuImageStatus.RLock()
1960 if pDevEntry.pOnuImageStatus != nil {
1961 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
1962 }
1963 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001964
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001965 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001966 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001967 }
1968 //MibDownload may run
1969 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1970 if pMibDlFsm != nil {
1971 _ = pMibDlFsm.Event(dlEvReset)
1972 }
1973 //port lock/unlock FSM's may be active
1974 if dh.pUnlockStateFsm != nil {
1975 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1976 }
1977 if dh.pLockStateFsm != nil {
1978 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1979 }
1980 //techProfile related PonAniConfigFsm FSM may be active
1981 if dh.pOnuTP != nil {
1982 // should always be the case here
1983 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1984 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001985 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001986 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001987 }
mpagenko900ee4b2020-10-12 11:56:34 +00001988 }
1989 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001990 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001991 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001992 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1993 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001994 dh.lockVlanConfig.RUnlock()
1995 //reset of all Fsm is always accompanied by global persistency data removal
1996 // no need to remove specific data
1997 pVlanFilterFsm.RequestClearPersistency(false)
1998 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001999 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002000 } else {
2001 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002002 }
2003 }
2004 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002005 if dh.getCollectorIsRunning() {
2006 // Stop collector routine
2007 dh.stopCollector <- true
2008 }
Himani Chawla1472c682021-03-17 17:11:14 +05302009 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302010 dh.stopAlarmManager <- true
2011 }
2012
mpagenko80622a52021-02-09 16:53:23 +00002013 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002014 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002015 dh.lockUpgradeFsm.RLock()
2016 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002017 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002018 }
2019 dh.lockUpgradeFsm.RUnlock()
2020
mpagenko7d6bb022021-03-11 15:07:55 +00002021 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002022 return nil
2023}
2024
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2026 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 +05302027
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002028 // store persistent data collected during MIB upload processing
2029 if err := dh.storePersistentData(ctx); err != nil {
2030 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2031 log.Fields{"device-id": dh.deviceID, "err": err})
2032 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002033 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002034 dh.addAllUniPorts(ctx)
2035
mpagenkoa40e99a2020-11-17 13:50:39 +00002036 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2037 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2038 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2039 * disable/enable toggling here to allow traffic
2040 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2041 * like the py comment says:
2042 * # start by locking all the unis till mib sync and initial mib is downloaded
2043 * # this way we can capture the port down/up events when we are ready
2044 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302045
mpagenkoa40e99a2020-11-17 13:50:39 +00002046 // Init Uni Ports to Admin locked state
2047 // *** should generate UniLockStateDone event *****
2048 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002050 } else { //LockStateFSM already init
2051 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002053 }
2054}
2055
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2057 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302058 /* Mib download procedure -
2059 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2060 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002062 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002063 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002064 return
2065 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302066 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2067 if pMibDlFsm != nil {
2068 if pMibDlFsm.Is(dlStDisabled) {
2069 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070 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 +05302071 // maybe try a FSM reset and then again ... - TODO!!!
2072 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302074 // maybe use more specific states here for the specific download steps ...
2075 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002076 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302077 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002078 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302079 //Begin MIB data download (running autonomously)
2080 }
2081 }
2082 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002083 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002084 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302085 // maybe try a FSM reset and then again ... - TODO!!!
2086 }
2087 /***** Mib download started */
2088 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302090 }
2091}
2092
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2094 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302095 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002096 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002097 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002098 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002099 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2100 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2101 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2102 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302104 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2105 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002106 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302107 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002108 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302109 }
2110 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302112 log.Fields{"device-id": dh.deviceID})
2113 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002114 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002115
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002116 if !dh.getCollectorIsRunning() {
2117 // Start PM collector routine
2118 go dh.startCollector(ctx)
2119 }
2120 if !dh.getAlarmManagerIsRunning(ctx) {
2121 go dh.startAlarmManager(ctx)
2122 }
2123
Girish Gowdrae0140f02021-02-02 16:55:09 -08002124 // Initialize classical L2 PM Interval Counters
2125 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2126 // There is no way we should be landing here, but if we do then
2127 // there is nothing much we can do about this other than log error
2128 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2129 }
2130
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002131 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002132
2133 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2134 if pDevEntry == nil {
2135 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2136 return
2137 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002138 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002139 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002140 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002141 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2142 log.Fields{"device-id": dh.deviceID})
2143 go dh.reconcileDeviceTechProf(ctx)
2144 // reconcilement will be continued after ani config is done
2145 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002146 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002147 // *** should generate UniUnlockStateDone event *****
2148 if dh.pUnlockStateFsm == nil {
2149 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2150 } else { //UnlockStateFSM already init
2151 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2152 dh.runUniLockFsm(ctx, false)
2153 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302154 }
2155}
2156
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2158 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302159
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002160 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002162 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2164 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002165 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002167 return
2168 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002169 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002170 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002171 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 if err := dh.storePersistentData(ctx); err != nil {
2173 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002174 log.Fields{"device-id": dh.deviceID, "err": err})
2175 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302176 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 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 +05302178 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002180 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302181 }
2182}
2183
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2185 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002186 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002188 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2189 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002191 }
2192
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002194 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002196
2197 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002199
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002201 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002203 return
2204 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002205 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002206 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002207 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 if err := dh.storePersistentData(ctx); err != nil {
2209 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002210 log.Fields{"device-id": dh.deviceID, "err": err})
2211 }
mpagenko900ee4b2020-10-12 11:56:34 +00002212}
2213
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2215 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002216 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002218 voltha.OperStatus_ACTIVE); err != nil {
2219 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002220 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002221 }
2222
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002224 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002225 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002227
2228 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002230
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002232 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002233 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002234 return
2235 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002236 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002237 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002238 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002239 if err := dh.storePersistentData(ctx); err != nil {
2240 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002241 log.Fields{"device-id": dh.deviceID, "err": err})
2242 }
mpagenko900ee4b2020-10-12 11:56:34 +00002243}
2244
dbainbri4d3a0dc2020-12-02 00:33:42 +00002245func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002246 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002248 // attention: the device reason update is done based on ONU-UNI-Port related activity
2249 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002250 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002251 // 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 +00002252 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302253 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002254 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002256 }
2257 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002259 // attention: the device reason update is done based on ONU-UNI-Port related activity
2260 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002261 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002262 // 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 +00002263 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002264 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002265 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302266}
2267
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2269 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002270 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302271 // attention: the device reason update is done based on ONU-UNI-Port related activity
2272 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302273
mpagenkof1fc3862021-02-16 10:09:52 +00002274 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002275 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002276 // which may be the case from some previous actvity on another UNI Port of the ONU
2277 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002278 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2279 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002280 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002281 }
2282 }
2283 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002284 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002285 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002287 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 }
mpagenkof1fc3862021-02-16 10:09:52 +00002289
2290 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2291 //events that request KvStore write
2292 if err := dh.storePersistentData(ctx); err != nil {
2293 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2294 log.Fields{"device-id": dh.deviceID, "err": err})
2295 }
2296 } else {
2297 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2298 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002299 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302300}
2301
Himani Chawla6d2ae152020-09-02 13:11:20 +05302302//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002303func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302304 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002305 case MibDatabaseSync:
2306 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002308 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002309 case UniLockStateDone:
2310 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002311 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002312 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002313 case MibDownloadDone:
2314 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002316 }
2317 case UniUnlockStateDone:
2318 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002320 }
mpagenko900ee4b2020-10-12 11:56:34 +00002321 case UniEnableStateDone:
2322 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002324 }
2325 case UniDisableStateDone:
2326 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002328 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002329 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002330 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002332 }
mpagenkof1fc3862021-02-16 10:09:52 +00002333 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002334 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002336 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002337 case OmciOnuSwUpgradeDone:
2338 {
2339 dh.upgradeSuccess = true
2340 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002341 default:
2342 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002344 }
2345 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002346}
2347
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002349 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302351 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002352 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002354 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302355 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002357 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002359 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002360 //store UniPort with the System-PortNumber key
2361 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002362 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002363 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2365 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002366 } //error logging already within UniPort method
2367 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002369 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002370 }
2371 }
2372}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002373
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002374func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2375 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2376 if pDevEntry == nil {
2377 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2378 return
2379 }
2380 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2381 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2382 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2383 for _, mgmtEntityID := range pptpInstKeys {
2384 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2385 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2386 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2387 i++
2388 }
2389 } else {
2390 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2391 }
2392 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2393 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2394 for _, mgmtEntityID := range veipInstKeys {
2395 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2396 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2397 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2398 i++
2399 }
2400 } else {
2401 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2402 }
2403 if i == 0 {
2404 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2405 }
2406}
2407
mpagenko3af1f032020-06-10 08:53:41 +00002408// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002409func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002410 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302411 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002412 // with following remark:
2413 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2414 // # load on the core
2415
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002416 // 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 +00002417
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002418 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002419 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302420 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002421 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302422 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002423 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002424 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002425 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 +00002426 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002427 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002428 }
mpagenko3af1f032020-06-10 08:53:41 +00002429 }
2430 }
2431}
2432
2433// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002434func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002435 // compare enableUniPortStateUpdate() above
2436 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2437 for uniNo, uniPort := range dh.uniEntityMap {
2438 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302439 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002440 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302441 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002442 if !dh.isReconciling() {
2443 //maybe also use getter functions on uniPort - perhaps later ...
2444 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2445 } else {
2446 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2447 }
2448
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002449 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002450 }
2451}
2452
2453// ONU_Active/Inactive announcement on system KAFKA bus
2454// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002456 var de voltha.DeviceEvent
2457 eventContext := make(map[string]string)
2458 //Populating event context
2459 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002461 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002462 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302463 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002464 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 +00002465 }
2466 oltSerialNumber := parentDevice.SerialNumber
2467
2468 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2469 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2470 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302471 eventContext["olt-serial-number"] = oltSerialNumber
2472 eventContext["device-id"] = aDeviceID
2473 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002474 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002475 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002476
2477 /* Populating device event body */
2478 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302479 de.ResourceId = aDeviceID
2480 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002481 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2482 de.Description = fmt.Sprintf("%s Event - %s - %s",
2483 cEventObjectType, cOnuActivatedEvent, "Raised")
2484 } else {
2485 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2486 de.Description = fmt.Sprintf("%s Event - %s - %s",
2487 cEventObjectType, cOnuActivatedEvent, "Cleared")
2488 }
2489 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2491 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302492 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002493 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302495 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002496}
2497
Himani Chawla4d908332020-08-31 12:30:20 +05302498// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002500 chLSFsm := make(chan Message, 2048)
2501 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302502 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002503 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002504 sFsmName = "LockStateFSM"
2505 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002506 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002507 sFsmName = "UnLockStateFSM"
2508 }
mpagenko3af1f032020-06-10 08:53:41 +00002509
dbainbri4d3a0dc2020-12-02 00:33:42 +00002510 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002511 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002513 return
2514 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002515 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002516 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002517 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302518 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002519 dh.pLockStateFsm = pLSFsm
2520 } else {
2521 dh.pUnlockStateFsm = pLSFsm
2522 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002524 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002525 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002526 }
2527}
2528
2529// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002530func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002531 /* Uni Port lock/unlock procedure -
2532 ***** should run via 'adminDone' state and generate the argument requested event *****
2533 */
2534 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302535 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002536 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2537 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2538 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002539 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302540 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002541 }
2542 } else {
2543 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2544 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2545 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002546 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302547 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002548 }
2549 }
2550 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002551 if pLSStatemachine.Is(uniStDisabled) {
2552 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002554 // maybe try a FSM reset and then again ... - TODO!!!
2555 } else {
2556 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002558 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002559 }
2560 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002561 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002562 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002563 // maybe try a FSM reset and then again ... - TODO!!!
2564 }
2565 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002567 // maybe try a FSM reset and then again ... - TODO!!!
2568 }
2569}
2570
mpagenko80622a52021-02-09 16:53:23 +00002571// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002572func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002573 //in here lockUpgradeFsm is already locked
2574 chUpgradeFsm := make(chan Message, 2048)
2575 var sFsmName = "OnuSwUpgradeFSM"
2576 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002577 if apDevEntry.PDevOmciCC == nil {
2578 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2579 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002580 }
mpagenko15ff4a52021-03-02 10:09:20 +00002581 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002582 sFsmName, chUpgradeFsm)
2583 if dh.pOnuUpradeFsm != nil {
2584 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2585 if pUpgradeStatemachine != nil {
2586 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002587 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002588 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2589 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2590 // maybe try a FSM reset and then again ... - TODO!!!
2591 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2592 }
2593 /***** LockStateFSM started */
2594 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2595 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2596 } else {
2597 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2598 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2599 // maybe try a FSM reset and then again ... - TODO!!!
2600 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2601 }
2602 } else {
2603 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2604 // maybe try a FSM reset and then again ... - TODO!!!
2605 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2606 }
2607 } else {
2608 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2609 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2610 }
2611 return nil
2612}
2613
2614// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2615func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2616 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2617 "device-id": dh.deviceID})
2618 dh.lockUpgradeFsm.Lock()
2619 defer dh.lockUpgradeFsm.Unlock()
2620 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2621}
2622
mpagenko15ff4a52021-03-02 10:09:20 +00002623// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2624func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2625 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2626 if pDevEntry == nil {
2627 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2628 return
2629 }
2630
2631 dh.lockUpgradeFsm.RLock()
2632 defer dh.lockUpgradeFsm.RUnlock()
2633 if dh.pOnuUpradeFsm != nil {
2634 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2635 if pUpgradeStatemachine != nil {
2636 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2637 // (some manual forced commit could do without)
2638 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002639 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002640 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2641 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2642 return
2643 }
2644 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2645 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2646 } else {
2647 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2648 log.Fields{"device-id": dh.deviceID})
2649 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2650 return
2651 }
2652 }
2653 }
2654 } else {
2655 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2656 }
2657}
2658
Himani Chawla6d2ae152020-09-02 13:11:20 +05302659//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002660func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002661
2662 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002663 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002664 kvbackend := &db.Backend{
2665 Client: dh.pOpenOnuAc.kvClient,
2666 StoreType: dh.pOpenOnuAc.KVStoreType,
2667 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002668 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002669 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2670 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002671
mpagenkoaf801632020-07-03 10:00:42 +00002672 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002673}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002674func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302675 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002676
mpagenkodff5dda2020-08-28 11:52:01 +00002677 for _, field := range flow.GetOfbFields(apFlowItem) {
2678 switch field.Type {
2679 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2680 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002681 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002682 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2683 }
mpagenko01e726e2020-10-23 09:45:29 +00002684 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002685 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2686 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302687 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002688 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302689 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2690 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002691 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2692 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002693 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2694 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302695 return
mpagenkodff5dda2020-08-28 11:52:01 +00002696 }
2697 }
mpagenko01e726e2020-10-23 09:45:29 +00002698 */
mpagenkodff5dda2020-08-28 11:52:01 +00002699 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2700 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302701 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002702 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302703 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002704 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302705 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002706 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002707 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302708 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002709 }
2710 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2711 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302712 *loAddPcp = uint8(field.GetVlanPcp())
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 "PCP": loAddPcp})
2715 }
2716 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
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 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2720 }
2721 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
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 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2725 }
2726 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2727 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002728 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002729 "IPv4-DST": field.GetIpv4Dst()})
2730 }
2731 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2732 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002733 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002734 "IPv4-SRC": field.GetIpv4Src()})
2735 }
2736 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2737 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002738 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002739 "Metadata": field.GetTableMetadata()})
2740 }
2741 /*
2742 default:
2743 {
2744 //all other entires ignored
2745 }
2746 */
2747 }
2748 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302749}
mpagenkodff5dda2020-08-28 11:52:01 +00002750
dbainbri4d3a0dc2020-12-02 00:33:42 +00002751func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002752 for _, action := range flow.GetActions(apFlowItem) {
2753 switch action.Type {
2754 /* not used:
2755 case of.OfpActionType_OFPAT_OUTPUT:
2756 {
mpagenko01e726e2020-10-23 09:45:29 +00002757 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002758 "Output": action.GetOutput()})
2759 }
2760 */
2761 case of.OfpActionType_OFPAT_PUSH_VLAN:
2762 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002763 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002764 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2765 }
2766 case of.OfpActionType_OFPAT_SET_FIELD:
2767 {
2768 pActionSetField := action.GetSetField()
2769 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002770 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002771 "OxcmClass": pActionSetField.Field.OxmClass})
2772 }
2773 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302774 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002775 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302776 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002777 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302778 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002779 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302780 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002781 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002783 "Type": pActionSetField.Field.GetOfbField().Type})
2784 }
2785 }
2786 /*
2787 default:
2788 {
2789 //all other entires ignored
2790 }
2791 */
2792 }
2793 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302794}
2795
2796//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002797func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302798 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2799 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2800 var loAddPcp, loSetPcp uint8
2801 var loIPProto uint32
2802 /* the TechProfileId is part of the flow Metadata - compare also comment within
2803 * OLT-Adapter:openolt_flowmgr.go
2804 * Metadata 8 bytes:
2805 * Most Significant 2 Bytes = Inner VLAN
2806 * Next 2 Bytes = Tech Profile ID(TPID)
2807 * Least Significant 4 Bytes = Port ID
2808 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2809 * subscriber related flows.
2810 */
2811
dbainbri4d3a0dc2020-12-02 00:33:42 +00002812 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302813 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002814 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302815 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002816 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302817 }
mpagenko551a4d42020-12-08 18:09:20 +00002818 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002819 loCookie := apFlowItem.GetCookie()
2820 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002821 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002822 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302823
dbainbri4d3a0dc2020-12-02 00:33:42 +00002824 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002825 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302826 if loIPProto == 2 {
2827 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2828 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002829 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2830 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302831 return nil
2832 }
mpagenko01e726e2020-10-23 09:45:29 +00002833 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002834 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002835
2836 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002837 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002838 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2839 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2840 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2841 //TODO!!: Use DeviceId within the error response to rwCore
2842 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002843 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002844 }
2845 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002846 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002847 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2848 } else {
2849 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2850 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2851 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302852 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002853 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002854 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002855 }
mpagenko9a304ea2020-12-16 15:54:01 +00002856
2857 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002858 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002859 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302860 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002861 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002862 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002863 dh.lockVlanConfig.RUnlock()
2864 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002865 }
mpagenkof1fc3862021-02-16 10:09:52 +00002866 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002867 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002868 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002869}
2870
2871//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002872func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002873 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2874 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2875 //no extra check is done on the rule parameters
2876 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2877 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2878 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2879 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002880 // - 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 +00002881 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002882 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002883
2884 /* TT related temporary workaround - should not be needed anymore
2885 for _, field := range flow.GetOfbFields(apFlowItem) {
2886 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2887 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002888 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002889 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2890 if loIPProto == 2 {
2891 // 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 +00002892 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002893 log.Fields{"device-id": dh.deviceID})
2894 return nil
2895 }
2896 }
2897 } //for all OfbFields
2898 */
2899
mpagenko9a304ea2020-12-16 15:54:01 +00002900 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002901 dh.lockVlanConfig.RLock()
2902 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002903 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002904 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002905 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002906 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002907 log.Fields{"device-id": dh.deviceID})
2908 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002909 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002910 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002911
mpagenko01e726e2020-10-23 09:45:29 +00002912 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002913}
2914
Himani Chawla26e555c2020-08-31 12:30:20 +05302915// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002916// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002917func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002918 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002919 chVlanFilterFsm := make(chan Message, 2048)
2920
dbainbri4d3a0dc2020-12-02 00:33:42 +00002921 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002922 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002923 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302924 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002925 }
2926
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002928 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002929 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002930 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002931 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002932 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2933 // (from parallel processing)
2934 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302935 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002936 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2937 if pVlanFilterStatemachine != nil {
2938 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2939 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002940 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302941 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002942 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302943 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002944 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302945 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2946 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002947 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002948 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002949 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302950 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002951 }
2952 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002953 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002954 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302955 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002956 }
2957 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002959 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302960 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002961 }
2962 return nil
2963}
2964
mpagenkofc4f56e2020-11-04 17:17:49 +00002965//VerifyVlanConfigRequest checks on existence of a given uniPort
2966// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002967func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002968 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2969 var pCurrentUniPort *onuUniPort
2970 for _, uniPort := range dh.uniEntityMap {
2971 // only if this port is validated for operState transfer
2972 if uniPort.uniID == uint8(aUniID) {
2973 pCurrentUniPort = uniPort
2974 break //found - end search loop
2975 }
2976 }
2977 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002978 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002979 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2980 return
2981 }
mpagenko551a4d42020-12-08 18:09:20 +00002982 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002983}
2984
mpagenkodff5dda2020-08-28 11:52:01 +00002985//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002986func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002987 //TODO!! verify and start pending flow configuration
2988 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2989 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002990
2991 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302992 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002993 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002994 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2995 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2996 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002997 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2998 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2999 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3000 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3001 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3002 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3003 } else {
3004 /***** UniVlanConfigFsm continued */
3005 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3006 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3007 "UniPort": apUniPort.portNo})
3008 }
3009 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3010 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3011 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3012 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3013 } else {
3014 /***** UniVlanConfigFsm continued */
3015 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3016 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3017 "UniPort": apUniPort.portNo})
3018 }
mpagenkodff5dda2020-08-28 11:52:01 +00003019 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003020 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3021 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003022 "UniPort": apUniPort.portNo})
3023 }
3024 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003025 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3026 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3027 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003028 }
3029 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003030 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003031 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003032 }
mpagenkof1fc3862021-02-16 10:09:52 +00003033 } else {
3034 dh.lockVlanConfig.RUnlock()
3035 }
mpagenkodff5dda2020-08-28 11:52:01 +00003036}
3037
3038//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3039// 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 +00003040func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3041 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003042 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3043 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003044 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303045 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003046 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003047}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003048
mpagenkof1fc3862021-02-16 10:09:52 +00003049//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3050func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3051 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3052 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3053 // obviously then parallel processing on the cancel must be avoided
3054 // deadline context to ensure completion of background routines waited for
3055 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3056 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3057 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3058
3059 aPDevEntry.resetKvProcessingErrorIndication()
3060 var wg sync.WaitGroup
3061 wg.Add(1) // for the 1 go routine to finish
3062
3063 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3064 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3065
3066 return aPDevEntry.getKvProcessingErrorIndication()
3067}
3068
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003069//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3070//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003071func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3072 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003073
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003074 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003076 return nil
3077 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003078 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003079
dbainbri4d3a0dc2020-12-02 00:33:42 +00003080 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003081 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003082 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003083 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3084 }
3085 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3086
mpagenkof1fc3862021-02-16 10:09:52 +00003087 if aWriteToKvStore {
3088 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3089 }
3090 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003091}
3092
dbainbri4d3a0dc2020-12-02 00:33:42 +00003093func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003094 defer cancel() //ensure termination of context (may be pro forma)
3095 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003096 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003097 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003098}
3099
dbainbri4d3a0dc2020-12-02 00:33:42 +00003100func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003101
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003102 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003103 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003104 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003105 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3106 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003107 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003108 return err
3109 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003110 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003111 return nil
3112 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003113 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003114 return nil
3115}
3116
dbainbri4d3a0dc2020-12-02 00:33:42 +00003117func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3118 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003119 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003120 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003121 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3122 }
mpagenkof1fc3862021-02-16 10:09:52 +00003123 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003124}
3125
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003126func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3127 var errStr string = ""
3128 for _, err := range errS {
3129 if err != nil {
3130 errStr = errStr + err.Error() + " "
3131 }
3132 }
3133 if errStr != "" {
3134 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3135 }
3136 return nil
3137}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003138
3139// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
3140func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3141 dh.lockDevice.RLock()
3142 defer dh.lockDevice.RUnlock()
3143 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3144 return uniPort.entityID, nil
3145 }
3146 return 0, errors.New("error-fetching-uni-port")
3147}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003148
3149// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003150func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3151 var errorsList []error
3152 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 -08003153
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003154 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3155 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3156 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3157
3158 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3159 // successfully.
3160 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3161 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3162 if len(errorsList) > 0 {
3163 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3164 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003165 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003166 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3167 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003168}
3169
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003170func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3171 var err error
3172 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003173 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003174
3175 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3176 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3177 errorsList = append(errorsList, err)
3178 }
3179 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003180 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003181
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003182 return errorsList
3183}
3184
3185func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3186 var err error
3187 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003188 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003189 // Check if group metric related config is updated
3190 for _, v := range pmConfigs.Groups {
3191 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3192 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3193 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3194
3195 if ok && m.frequency != v.GroupFreq {
3196 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3197 errorsList = append(errorsList, err)
3198 }
3199 }
3200 if ok && m.enabled != v.Enabled {
3201 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3202 errorsList = append(errorsList, err)
3203 }
3204 }
3205 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003206 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003207 return errorsList
3208}
3209
3210func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3211 var err error
3212 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003213 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003214 // Check if standalone metric related config is updated
3215 for _, v := range pmConfigs.Metrics {
3216 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003217 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003218 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3219
3220 if ok && m.frequency != v.SampleFreq {
3221 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3222 errorsList = append(errorsList, err)
3223 }
3224 }
3225 if ok && m.enabled != v.Enabled {
3226 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3227 errorsList = append(errorsList, err)
3228 }
3229 }
3230 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003231 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003232 return errorsList
3233}
3234
3235// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003236func (dh *deviceHandler) startCollector(ctx context.Context) {
3237 logger.Debugf(ctx, "startingCollector")
3238
3239 // Start routine to process OMCI GET Responses
3240 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003241 // Initialize the next metric collection time.
3242 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3243 // reset like onu rebooted.
3244 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003245 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003246 for {
3247 select {
3248 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003249 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003250 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003251 // Stop the L2 PM FSM
3252 go func() {
3253 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3254 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3255 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3256 }
3257 } else {
3258 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3259 }
3260 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003261 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3262 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3263 }
3264 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3265 dh.pOnuMetricsMgr.stopTicks <- true
3266 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003267
Girish Gowdrae09a6202021-01-12 18:10:59 -08003268 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003269 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3270 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3271 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3272 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3273 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003274 // Update the next metric collection time.
3275 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003276 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003277 } else {
3278 if dh.pmConfigs.Grouped { // metrics are managed as a group
3279 // parse through the group and standalone metrics to see it is time to collect their metrics
3280 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003281
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003282 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3283 // 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 -08003284 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3285 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003286 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3287 }
3288 }
3289 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3290 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3291 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3292 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3293 }
3294 }
3295 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3296
3297 // parse through the group and update the next metric collection time
3298 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3299 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3300 // 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 -08003301 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3302 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003303 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3304 }
3305 }
3306 // parse through the standalone metrics and update the next metric collection time
3307 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3308 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3309 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3310 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3311 }
3312 }
3313 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3314 } /* else { // metrics are not managed as a group
3315 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3316 } */
3317 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003318 }
3319 }
3320}
kesavandfdf77632021-01-26 23:40:33 -05003321
3322func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3323
3324 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3325 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3326}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003327
mpagenkof1fc3862021-02-16 10:09:52 +00003328func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3329 if pFsm == nil {
3330 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003331 }
mpagenkof1fc3862021-02-16 10:09:52 +00003332 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003333}
3334
mpagenkof1fc3862021-02-16 10:09:52 +00003335func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3336 var pFsm *fsm.FSM
3337 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3338 switch omciFsm {
3339 case cUploadFsm:
3340 {
3341 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3342 }
3343 case cDownloadFsm:
3344 {
3345 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3346 }
3347 case cUniLockFsm:
3348 {
3349 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3350 }
3351 case cUniUnLockFsm:
3352 {
3353 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3354 }
3355 case cL2PmFsm:
3356 {
3357 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3358 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3359 } else {
3360 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003361 }
3362 }
mpagenko80622a52021-02-09 16:53:23 +00003363 case cOnuUpgradeFsm:
3364 {
3365 dh.lockUpgradeFsm.RLock()
3366 defer dh.lockUpgradeFsm.RUnlock()
3367 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3368 }
mpagenkof1fc3862021-02-16 10:09:52 +00003369 default:
3370 {
3371 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3372 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3373 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003374 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003375 }
mpagenkof1fc3862021-02-16 10:09:52 +00003376 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003377}
3378
mpagenkof1fc3862021-02-16 10:09:52 +00003379func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3380 for _, v := range dh.pOnuTP.pAniConfigFsm {
3381 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003382 return false
3383 }
3384 }
3385 return true
3386}
3387
mpagenkof1fc3862021-02-16 10:09:52 +00003388func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3389 dh.lockVlanConfig.RLock()
3390 defer dh.lockVlanConfig.RUnlock()
3391 for _, v := range dh.UniVlanConfigFsmMap {
3392 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3393 return false
3394 }
3395 }
3396 return true //FSM not active - so there is no activity on omci
3397}
3398
3399func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3400 dh.lockVlanConfig.RLock()
3401 defer dh.lockVlanConfig.RUnlock()
3402 for _, v := range dh.UniVlanConfigFsmMap {
3403 if v.pAdaptFsm.pFsm != nil {
3404 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3405 return true //there is at least one VLAN FSM with some active configuration
3406 }
3407 }
3408 }
3409 return false //there is no VLAN FSM with some active configuration
3410}
3411
3412func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3413 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3414 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3415 return false
3416 }
3417 }
3418 // a further check is done to identify, if at least some data traffic related configuration exists
3419 // 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])
3420 return dh.checkUserServiceExists(ctx)
3421}
3422
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003423func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3424 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3425 if err := dh.resetFsms(ctx, false); err != nil {
3426 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3427 // TODO: fatal error reset ONU, delete deviceHandler!
3428 return
3429 }
3430 if !dh.getCollectorIsRunning() {
3431 // Start PM collector routine
3432 go dh.startCollector(ctx)
3433 }
Himani Chawla1472c682021-03-17 17:11:14 +05303434 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303435 go dh.startAlarmManager(ctx)
3436 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003437 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003438 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003439}
3440
3441func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3442 dh.mutexCollectorFlag.Lock()
3443 dh.collectorIsRunning = flagValue
3444 dh.mutexCollectorFlag.Unlock()
3445}
3446
3447func (dh *deviceHandler) getCollectorIsRunning() bool {
3448 dh.mutexCollectorFlag.RLock()
3449 flagValue := dh.collectorIsRunning
3450 dh.mutexCollectorFlag.RUnlock()
3451 return flagValue
3452}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303453
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303454func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3455 dh.mutextAlarmManagerFlag.Lock()
3456 dh.alarmManagerIsRunning = flagValue
3457 dh.mutextAlarmManagerFlag.Unlock()
3458}
3459
Himani Chawla1472c682021-03-17 17:11:14 +05303460func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303461 dh.mutextAlarmManagerFlag.RLock()
3462 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303463 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303464 dh.mutextAlarmManagerFlag.RUnlock()
3465 return flagValue
3466}
3467
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303468func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3469 logger.Debugf(ctx, "startingAlarmManager")
3470
3471 // Start routine to process OMCI GET Responses
3472 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303473 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303474 if stop := <-dh.stopAlarmManager; stop {
3475 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303476 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303477 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303478 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3479 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3480 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303481 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303482 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303483 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3484 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303485 }
3486}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003487
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003488func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003489 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003490
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003491 if !dh.isReconciling() {
3492 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003493 logger.Debugw(ctx, "wait for channel signal or timeout",
3494 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003495 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003496 case success := <-dh.chReconcilingFinished:
3497 if success {
Maninderb5187552021-03-23 22:23:42 +05303498 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3499 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3500 log.Fields{"device-id": dh.deviceID})
3501 } else {
3502 connectStatus := voltha.ConnectStatus_UNREACHABLE
3503 operState := voltha.OperStatus_UNKNOWN
3504 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3505 connectStatus = voltha.ConnectStatus_REACHABLE
3506 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3507 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3508 operState = voltha.OperStatus_ACTIVE
3509 } else {
3510 operState = voltha.OperStatus_ACTIVATING
3511 }
3512 }
3513 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3514 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3515 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3516 operState = voltha.OperStatus_DISCOVERED
3517 }
3518
3519 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
3520 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3521 logger.Errorw(ctx, "unable to update device state to core",
3522 log.Fields{"OperState": onuDevEntry.sOnuPersistentData.PersOperState, "Err": err})
3523 }
3524 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003525 logger.Debugw(ctx, "reconciling has been finished in time",
3526 log.Fields{"device-id": dh.deviceID})
3527 } else {
Maninderb5187552021-03-23 22:23:42 +05303528 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003529 log.Fields{"device-id": dh.deviceID})
3530 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003531 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Maninderb5187552021-03-23 22:23:42 +05303532 //TODO: handle notification to core if reconciling timed out
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003533 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3534 log.Fields{"device-id": dh.deviceID})
3535 }
3536 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003537 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003538 dh.mutexReconcilingFlag.Unlock()
3539 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003540 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003541 dh.mutexReconcilingFlag.Lock()
3542 if skipOnuConfig {
3543 dh.reconciling = cSkipOnuConfigReconciling
3544 } else {
3545 dh.reconciling = cOnuConfigReconciling
3546 }
3547 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003548}
3549
3550func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3551 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3552 if dh.isReconciling() {
3553 dh.chReconcilingFinished <- true
3554 } else {
3555 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3556 }
3557}
3558
3559func (dh *deviceHandler) isReconciling() bool {
3560 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003561 defer dh.mutexReconcilingFlag.RUnlock()
3562 return dh.reconciling != cNoReconciling
3563}
3564
3565func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3566 dh.mutexReconcilingFlag.RLock()
3567 defer dh.mutexReconcilingFlag.RUnlock()
3568 return dh.reconciling == cSkipOnuConfigReconciling
3569}
3570
3571func (dh *deviceHandler) setDeviceReason(value uint8) {
3572 dh.mutexDeviceReason.Lock()
3573 dh.deviceReason = value
3574 dh.mutexDeviceReason.Unlock()
3575}
3576
3577func (dh *deviceHandler) getDeviceReason() uint8 {
3578 dh.mutexDeviceReason.RLock()
3579 value := dh.deviceReason
3580 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003581 return value
3582}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003583
3584func (dh *deviceHandler) getDeviceReasonString() string {
3585 return deviceReasonMap[dh.getDeviceReason()]
3586}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003587
3588func (dh *deviceHandler) setReconcilingFlows(value bool) {
3589 dh.mutexReconcilingFlowsFlag.Lock()
3590 dh.reconcilingFlows = value
3591 dh.mutexReconcilingFlowsFlag.Unlock()
3592}
3593
3594func (dh *deviceHandler) isReconcilingFlows() bool {
3595 dh.mutexReconcilingFlowsFlag.RLock()
3596 value := dh.reconcilingFlows
3597 dh.mutexReconcilingFlowsFlag.RUnlock()
3598 return value
3599}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003600
3601func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3602 dh.mutexReadyForOmciConfig.Lock()
3603 dh.readyForOmciConfig = flagValue
3604 dh.mutexReadyForOmciConfig.Unlock()
3605}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003606func (dh *deviceHandler) isReadyForOmciConfig() bool {
3607 dh.mutexReadyForOmciConfig.RLock()
3608 flagValue := dh.readyForOmciConfig
3609 dh.mutexReadyForOmciConfig.RUnlock()
3610 return flagValue
3611}