blob: da6936f79494c9185bf193e2213928c3d211f249 [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
mpagenko183647c2021-06-08 15:25:04 +00001185func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1186 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001187 var err error
1188 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1189 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1190 // 2.) activation of the inactive image
1191
1192 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1193 if pDevEntry == nil {
1194 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001195 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001196 }
1197 dh.lockUpgradeFsm.RLock()
1198 if dh.pOnuUpradeFsm != nil {
1199 dh.lockUpgradeFsm.RUnlock()
1200 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1201 dh.deviceID, dh.deviceID)
1202 if getErr != nil || onuVolthaDevice == nil {
1203 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001204 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001205 }
1206 // use the OnuVendor identification from this device for the internal unique name
1207 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1208 // 1.) check a started upgrade process and rely the activation request to it
1209 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001210 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001211 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1212 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001213 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001214 }
mpagenko183647c2021-06-08 15:25:04 +00001215 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1216 "device-id": dh.deviceID, "image-id": imageIdentifier})
1217 var pImageStates *voltha.ImageState
1218 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1219 pImageStates = &voltha.ImageState{}
1220 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1221 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1222 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1223 }
1224 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001225 } //else
1226 dh.lockUpgradeFsm.RUnlock()
1227
1228 // 2.) check if requested image-version equals the inactive one and start its activation
1229 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1230 var inactiveImageID uint16
1231 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1232 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1233 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001234 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001235 }
1236 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1237 if err == nil {
1238 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1239 inactiveImageID, aCommitRequest); err != nil {
1240 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1241 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001242 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001243 }
1244 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1245 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001246 var pImageStates *voltha.ImageState
1247 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1248 pImageStates := &voltha.ImageState{}
1249 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1250 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1251 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1252 }
1253 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001254 } //else
1255 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1256 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001257 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001258}
1259
1260//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001261func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1262 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001263 var err error
1264 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1265 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1266 // 2.) commitment of the active image
1267
1268 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1269 if pDevEntry == nil {
1270 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001271 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001272 }
1273 dh.lockUpgradeFsm.RLock()
1274 if dh.pOnuUpradeFsm != nil {
1275 dh.lockUpgradeFsm.RUnlock()
1276 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1277 dh.deviceID, dh.deviceID)
1278 if getErr != nil || onuVolthaDevice == nil {
1279 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001280 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 }
1282 // use the OnuVendor identification from this device for the internal unique name
1283 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1284 // 1.) check a started upgrade process and rely the commitment request to it
1285 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001286 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001287 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1288 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001289 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001290 }
mpagenko183647c2021-06-08 15:25:04 +00001291 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1292 "device-id": dh.deviceID, "image-id": imageIdentifier})
1293 var pImageStates *voltha.ImageState
1294 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1295 pImageStates := &voltha.ImageState{}
1296 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1297 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1298 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1299 }
1300 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001301 } //else
1302 dh.lockUpgradeFsm.RUnlock()
1303
mpagenko183647c2021-06-08 15:25:04 +00001304 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001305 var activeImageID uint16
1306 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1307 logger.Errorw(ctx, "get active image failed", log.Fields{
1308 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001309 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 }
1311 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1312 if err == nil {
1313 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1314 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1315 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001316 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001317 }
1318 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1319 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001320 var pImageStates *voltha.ImageState
1321 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1322 pImageStates := &voltha.ImageState{}
1323 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1324 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1325 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1326 }
1327 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001328 } //else
1329 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1330 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001331 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001332}
1333
mpagenkoaa3afe92021-05-21 16:20:58 +00001334func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1335 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1336 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001337 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001338 dh.lockUpgradeFsm.RLock()
1339 if dh.pOnuUpradeFsm != nil {
1340 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001341 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001342 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1343 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1344 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1345 } else {
1346 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1347 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1348 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1349 }
1350 } else {
1351 dh.lockUpgradeFsm.RUnlock()
1352 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1353 if dh.upgradeSuccess {
1354 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1355 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1356 } else {
1357 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1358 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1359 }
1360 }
1361}
1362
1363func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1364 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1365 pDeviceImageState.DeviceId = dh.deviceID
1366 pDeviceImageState.ImageState.Version = aImageIdentifier
1367 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1368 dh.lockUpgradeFsm.RLock()
1369 if dh.pOnuUpradeFsm != nil {
1370 dh.lockUpgradeFsm.RUnlock()
1371 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1372 // by now just straightforward assume this to be true
1373 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1374 //nolint:misspell
1375 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1376 //nolint:misspell
1377 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1378 } else {
1379 dh.lockUpgradeFsm.RUnlock()
1380 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1381 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1382 }
1383}
1384
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001385func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1386
1387 var onuImageStatus *OnuImageStatus
1388
1389 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1390 if pDevEntry != nil {
1391 onuImageStatus = NewOnuImageStatus(pDevEntry)
1392 pDevEntry.mutexOnuImageStatus.Lock()
1393 pDevEntry.pOnuImageStatus = onuImageStatus
1394 pDevEntry.mutexOnuImageStatus.Unlock()
1395
1396 } else {
1397 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1398 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1399 }
1400 images, err := onuImageStatus.getOnuImageStatus(ctx)
1401 pDevEntry.mutexOnuImageStatus.Lock()
1402 pDevEntry.pOnuImageStatus = nil
1403 pDevEntry.mutexOnuImageStatus.Unlock()
1404 return images, err
1405}
1406
Himani Chawla6d2ae152020-09-02 13:11:20 +05301407// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001408// #####################################################################################
1409
1410// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301411// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001412
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1414 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 +00001415}
1416
1417// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001419
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001421 var err error
1422
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001423 // populate what we know. rest comes later after mib sync
1424 dh.device.Root = false
1425 dh.device.Vendor = "OpenONU"
1426 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001427 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001428 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001429
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001430 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001431
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001432 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1434 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301435 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001436 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001438 log.Fields{"device-id": dh.deviceID})
1439 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440
Himani Chawla4d908332020-08-31 12:30:20 +05301441 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001442 dh.ponPortNumber = dh.device.ParentPortNo
1443
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001444 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1445 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1446 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001448 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301449 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001450
1451 /*
1452 self._pon = PonPort.create(self, self._pon_port_number)
1453 self._pon.add_peer(self.parent_id, self._pon_port_number)
1454 self.logger.debug('adding-pon-port-to-agent',
1455 type=self._pon.get_port().type,
1456 admin_state=self._pon.get_port().admin_state,
1457 oper_status=self._pon.get_port().oper_status,
1458 )
1459 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001460 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001461 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001462 var ponPortNo uint32 = 1
1463 if dh.ponPortNumber != 0 {
1464 ponPortNo = dh.ponPortNumber
1465 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001467 pPonPort := &voltha.Port{
1468 PortNo: ponPortNo,
1469 Label: fmt.Sprintf("pon-%d", ponPortNo),
1470 Type: voltha.Port_PON_ONU,
1471 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301472 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001473 PortNo: ponPortNo}}, // Peer port is parent's port number
1474 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1476 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001477 e.Cancel(err)
1478 return
1479 }
1480 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001482 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001484}
1485
1486// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001488
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001490 var err error
1491 /*
1492 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1493 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1494 return nil
1495 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1497 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001498 e.Cancel(err)
1499 return
1500 }
1501
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001502 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001504 // reconcilement will be continued after mib download is done
1505 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001506
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001507 /*
1508 ############################################################################
1509 # Setup Alarm handler
1510 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1511 device.serial_number)
1512 ############################################################################
1513 # Setup PM configuration for this device
1514 # Pass in ONU specific options
1515 kwargs = {
1516 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1517 'heartbeat': self.heartbeat,
1518 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1519 }
1520 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1521 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1522 self.logical_device_id, device.serial_number,
1523 grouped=True, freq_override=False, **kwargs)
1524 pm_config = self._pm_metrics.make_proto()
1525 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1526 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1527 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1528
1529 # Note, ONU ID and UNI intf set in add_uni_port method
1530 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1531 ani_ports=[self._pon])
1532
1533 # Code to Run OMCI Test Action
1534 kwargs_omci_test_action = {
1535 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1536 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1537 }
1538 serial_number = device.serial_number
1539 self._test_request = OmciTestRequest(self.core_proxy,
1540 self.omci_agent, self.device_id,
1541 AniG, serial_number,
1542 self.logical_device_id,
1543 exclusive=False,
1544 **kwargs_omci_test_action)
1545
1546 self.enabled = True
1547 else:
1548 self.logger.info('onu-already-activated')
1549 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001550
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001552}
1553
1554// doStateConnected get the device info and update to voltha core
1555// for comparison of the original method (not that easy to uncomment): compare here:
1556// voltha-openolt-adapter/adaptercore/device_handler.go
1557// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301561 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001562 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001564}
1565
1566// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001568
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301570 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001571 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573
1574 /*
1575 // Synchronous call to update device state - this method is run in its own go routine
1576 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1577 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001578 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 +00001579 return err
1580 }
1581 return nil
1582 */
1583}
1584
1585// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001587
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 var err error
1590
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001591 device := dh.device
1592 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001593 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001595 e.Cancel(err)
1596 return
1597 }
1598
1599 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601 /*
1602 // Update the all ports state on that device to disable
1603 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001604 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001605 return er
1606 }
1607
1608 //Update the device oper state and connection status
1609 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1610 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1611 dh.device = cloned
1612
1613 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001614 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615 return er
1616 }
1617
1618 //get the child device for the parent device
1619 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1620 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001621 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001622 return err
1623 }
1624 for _, onuDevice := range onuDevices.Items {
1625
1626 // Update onu state as down in onu adapter
1627 onuInd := oop.OnuIndication{}
1628 onuInd.OperState = "down"
1629 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1630 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1631 if er != nil {
1632 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001633 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634 //Do not return here and continue to process other ONUs
1635 }
1636 }
1637 // * Discovered ONUs entries need to be cleared , since after OLT
1638 // is up, it starts sending discovery indications again* /
1639 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001640 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001641 return nil
1642 */
Himani Chawla4d908332020-08-31 12:30:20 +05301643 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646}
1647
Himani Chawla6d2ae152020-09-02 13:11:20 +05301648// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649// #################################################################################
1650
1651// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301652// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001654//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001656 dh.lockDevice.RLock()
1657 pOnuDeviceEntry := dh.pOnuOmciDevice
1658 if aWait && pOnuDeviceEntry == nil {
1659 //keep the read sema short to allow for subsequent write
1660 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001662 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1663 // so it might be needed to wait here for that event with some timeout
1664 select {
1665 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001667 return nil
1668 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001670 // if written now, we can return the written value without sema
1671 return dh.pOnuOmciDevice
1672 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001673 }
mpagenko3af1f032020-06-10 08:53:41 +00001674 dh.lockDevice.RUnlock()
1675 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676}
1677
Himani Chawla6d2ae152020-09-02 13:11:20 +05301678//setOnuDeviceEntry sets the ONU device entry within the handler
1679func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001680 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681 dh.lockDevice.Lock()
1682 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001683 dh.pOnuOmciDevice = apDeviceEntry
1684 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001685 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301686 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001687 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688}
1689
Himani Chawla6d2ae152020-09-02 13:11:20 +05301690//addOnuDeviceEntry creates a new ONU device or returns the existing
1691func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 if deviceEntry == nil {
1696 /* costum_me_map in python code seems always to be None,
1697 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1698 /* also no 'clock' argument - usage open ...*/
1699 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001700 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001701 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001702 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301703 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001704 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001706 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001707 // fire deviceEntry ready event to spread to possibly waiting processing
1708 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001711 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712 }
1713 // might be updated with some error handling !!!
1714 return nil
1715}
1716
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1718 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001719 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1720
1721 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001722
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1727 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001728 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 if err := dh.storePersistentData(ctx); err != nil {
1730 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001731 log.Fields{"device-id": dh.deviceID, "err": err})
1732 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001734 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001736 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1737 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001739 }
1740 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001742 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001743
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001744 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001745 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001746 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 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 +00001748 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001749 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001750 } else {
1751 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001752 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001754 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1755 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1756 // 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 +00001757 // 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 +00001758 // so let's just try to keep it simple ...
1759 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001761 if err != nil || device == nil {
1762 //TODO: needs to handle error scenarios
1763 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1764 return errors.New("Voltha Device not found")
1765 }
1766 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001767
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001769 return err
mpagenko3af1f032020-06-10 08:53:41 +00001770 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001771
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001772 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001773
1774 /* this might be a good time for Omci Verify message? */
1775 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001777 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001778 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780
1781 /* give the handler some time here to wait for the OMCi verification result
1782 after Timeout start and try MibUpload FSM anyway
1783 (to prevent stopping on just not supported OMCI verification from ONU) */
1784 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001785 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789 }
1790
1791 /* In py code it looks earlier (on activate ..)
1792 # Code to Run OMCI Test Action
1793 kwargs_omci_test_action = {
1794 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1795 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1796 }
1797 serial_number = device.serial_number
1798 self._test_request = OmciTestRequest(self.core_proxy,
1799 self.omci_agent, self.device_id,
1800 AniG, serial_number,
1801 self.logical_device_id,
1802 exclusive=False,
1803 **kwargs_omci_test_action)
1804 ...
1805 # Start test requests after a brief pause
1806 if not self._test_request_started:
1807 self._test_request_started = True
1808 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1809 reactor.callLater(tststart, self._test_request.start_collector)
1810
1811 */
1812 /* which is then: in omci_test_request.py : */
1813 /*
1814 def start_collector(self, callback=None):
1815 """
1816 Start the collection loop for an adapter if the frequency > 0
1817
1818 :param callback: (callable) Function to call to collect PM data
1819 """
1820 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1821 if callback is None:
1822 callback = self.perform_test_omci
1823
1824 if self.lc is None:
1825 self.lc = LoopingCall(callback)
1826
1827 if self.default_freq > 0:
1828 self.lc.start(interval=self.default_freq / 10)
1829
1830 def perform_test_omci(self):
1831 """
1832 Perform the initial test request
1833 """
1834 ani_g_entities = self._device.configuration.ani_g_entities
1835 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1836 is not None else None
1837 self._entity_id = ani_g_entities_ids[0]
1838 self.logger.info('perform-test', entity_class=self._entity_class,
1839 entity_id=self._entity_id)
1840 try:
1841 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1842 result = yield self._device.omci_cc.send(frame)
1843 if not result.fields['omci_message'].fields['success_code']:
1844 self.logger.info('Self-Test Submitted Successfully',
1845 code=result.fields[
1846 'omci_message'].fields['success_code'])
1847 else:
1848 raise TestFailure('Test Failure: {}'.format(
1849 result.fields['omci_message'].fields['success_code']))
1850 except TimeoutError as e:
1851 self.deferred.errback(failure.Failure(e))
1852
1853 except Exception as e:
1854 self.logger.exception('perform-test-Error', e=e,
1855 class_id=self._entity_class,
1856 entity_id=self._entity_id)
1857 self.deferred.errback(failure.Failure(e))
1858
1859 */
1860
1861 // PM related heartbeat??? !!!TODO....
1862 //self._heartbeat.enabled = True
1863
mpagenko1cc3cb42020-07-27 15:24:38 +00001864 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1865 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1866 * 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 +05301867 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001868 */
1869 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001870 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001871 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001872 if pMibUlFsm.Is(ulStDisabled) {
1873 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 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 +00001875 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301876 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301878 //Determine ONU status and start/re-start MIB Synchronization tasks
1879 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001880 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301881 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 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 +00001883 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001884 }
Himani Chawla4d908332020-08-31 12:30:20 +05301885 } else {
1886 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 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 +00001888 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301889 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001891 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001892 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001894 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001895 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896 }
1897 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001899 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001900 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001901
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001902 if !dh.getCollectorIsRunning() {
1903 // Start PM collector routine
1904 go dh.startCollector(ctx)
1905 }
Himani Chawla1472c682021-03-17 17:11:14 +05301906 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301907 go dh.startAlarmManager(ctx)
1908 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301909
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001910 return nil
1911}
1912
dbainbri4d3a0dc2020-12-02 00:33:42 +00001913func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001914 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001915 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001916 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001917 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001918
mpagenko900ee4b2020-10-12 11:56:34 +00001919 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1920 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1921 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001922 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001924 log.Fields{"device-id": dh.deviceID, "error": err})
1925 // abort: system behavior is just unstable ...
1926 return err
1927 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001928 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 _ = 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 +00001930
1931 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1932 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1933 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001935 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001937 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001938 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001940
1941 //TODO!!! remove existing traffic profiles
1942 /* from py code, if TP's exist, remove them - not yet implemented
1943 self._tp = dict()
1944 # Let TP download happen again
1945 for uni_id in self._tp_service_specific_task:
1946 self._tp_service_specific_task[uni_id].clear()
1947 for uni_id in self._tech_profile_download_done:
1948 self._tech_profile_download_done[uni_id].clear()
1949 */
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001952
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001953 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001954
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001956 // abort: system behavior is just unstable ...
1957 return err
1958 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001960 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001962 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001963 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001965 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001966 // abort: system behavior is just unstable ...
1967 return err
1968 }
1969 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001971 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001972 return nil
1973}
1974
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001975func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001976 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1977 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1978 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1979 // and using the stop/reset event should never harm
1980
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001982 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001984 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1985 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001986 if pDevEntry.PDevOmciCC != nil {
1987 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1988 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001989 pDevEntry.mutexOnuImageStatus.RLock()
1990 if pDevEntry.pOnuImageStatus != nil {
1991 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
1992 }
1993 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001994
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001995 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001996 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001997 }
1998 //MibDownload may run
1999 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2000 if pMibDlFsm != nil {
2001 _ = pMibDlFsm.Event(dlEvReset)
2002 }
2003 //port lock/unlock FSM's may be active
2004 if dh.pUnlockStateFsm != nil {
2005 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2006 }
2007 if dh.pLockStateFsm != nil {
2008 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2009 }
2010 //techProfile related PonAniConfigFsm FSM may be active
2011 if dh.pOnuTP != nil {
2012 // should always be the case here
2013 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2014 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002015 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002016 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002017 }
mpagenko900ee4b2020-10-12 11:56:34 +00002018 }
2019 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002020 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002021 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002022 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2023 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002024 dh.lockVlanConfig.RUnlock()
2025 //reset of all Fsm is always accompanied by global persistency data removal
2026 // no need to remove specific data
2027 pVlanFilterFsm.RequestClearPersistency(false)
2028 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002029 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002030 } else {
2031 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002032 }
2033 }
2034 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002035 if dh.getCollectorIsRunning() {
2036 // Stop collector routine
2037 dh.stopCollector <- true
2038 }
Himani Chawla1472c682021-03-17 17:11:14 +05302039 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302040 dh.stopAlarmManager <- true
2041 }
2042
mpagenko80622a52021-02-09 16:53:23 +00002043 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002044 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002045 dh.lockUpgradeFsm.RLock()
2046 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002047 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002048 }
2049 dh.lockUpgradeFsm.RUnlock()
2050
mpagenko7d6bb022021-03-11 15:07:55 +00002051 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002052 return nil
2053}
2054
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2056 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 +05302057
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002058 // store persistent data collected during MIB upload processing
2059 if err := dh.storePersistentData(ctx); err != nil {
2060 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2061 log.Fields{"device-id": dh.deviceID, "err": err})
2062 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002063 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002064 dh.addAllUniPorts(ctx)
2065
mpagenkoa40e99a2020-11-17 13:50:39 +00002066 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2067 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2068 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2069 * disable/enable toggling here to allow traffic
2070 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2071 * like the py comment says:
2072 * # start by locking all the unis till mib sync and initial mib is downloaded
2073 * # this way we can capture the port down/up events when we are ready
2074 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302075
mpagenkoa40e99a2020-11-17 13:50:39 +00002076 // Init Uni Ports to Admin locked state
2077 // *** should generate UniLockStateDone event *****
2078 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002080 } else { //LockStateFSM already init
2081 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002083 }
2084}
2085
dbainbri4d3a0dc2020-12-02 00:33:42 +00002086func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2087 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302088 /* Mib download procedure -
2089 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2090 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002092 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002093 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002094 return
2095 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302096 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2097 if pMibDlFsm != nil {
2098 if pMibDlFsm.Is(dlStDisabled) {
2099 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002100 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 +05302101 // maybe try a FSM reset and then again ... - TODO!!!
2102 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302104 // maybe use more specific states here for the specific download steps ...
2105 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002106 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302107 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002108 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302109 //Begin MIB data download (running autonomously)
2110 }
2111 }
2112 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002114 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302115 // maybe try a FSM reset and then again ... - TODO!!!
2116 }
2117 /***** Mib download started */
2118 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302120 }
2121}
2122
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2124 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002126 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002128 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002129 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2130 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2131 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2132 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302134 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2135 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302137 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302139 }
2140 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 log.Fields{"device-id": dh.deviceID})
2143 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002144 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002145
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002146 if !dh.getCollectorIsRunning() {
2147 // Start PM collector routine
2148 go dh.startCollector(ctx)
2149 }
2150 if !dh.getAlarmManagerIsRunning(ctx) {
2151 go dh.startAlarmManager(ctx)
2152 }
2153
Girish Gowdrae0140f02021-02-02 16:55:09 -08002154 // Initialize classical L2 PM Interval Counters
2155 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2156 // There is no way we should be landing here, but if we do then
2157 // there is nothing much we can do about this other than log error
2158 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2159 }
2160
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002161 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002162
2163 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2164 if pDevEntry == nil {
2165 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2166 return
2167 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002168 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002169 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002170 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002171 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2172 log.Fields{"device-id": dh.deviceID})
2173 go dh.reconcileDeviceTechProf(ctx)
2174 // reconcilement will be continued after ani config is done
2175 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002176 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002177 // *** should generate UniUnlockStateDone event *****
2178 if dh.pUnlockStateFsm == nil {
2179 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2180 } else { //UnlockStateFSM already init
2181 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2182 dh.runUniLockFsm(ctx, false)
2183 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302184 }
2185}
2186
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2188 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302189
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002190 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002192 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2194 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002195 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002197 return
2198 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002199 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002200 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002201 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 if err := dh.storePersistentData(ctx); err != nil {
2203 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002204 log.Fields{"device-id": dh.deviceID, "err": err})
2205 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302206 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207 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 +05302208 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002210 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302211 }
2212}
2213
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2215 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002216 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002218 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); 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 disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002224 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002226
2227 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002229
dbainbri4d3a0dc2020-12-02 00:33:42 +00002230 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002231 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002232 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002233 return
2234 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002235 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002236 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002237 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238 if err := dh.storePersistentData(ctx); err != nil {
2239 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002240 log.Fields{"device-id": dh.deviceID, "err": err})
2241 }
mpagenko900ee4b2020-10-12 11:56:34 +00002242}
2243
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2245 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002246 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002248 voltha.OperStatus_ACTIVE); err != nil {
2249 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002250 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002251 }
2252
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002254 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002255 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002257
2258 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002260
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002262 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002263 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002264 return
2265 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002266 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002267 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002268 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 if err := dh.storePersistentData(ctx); err != nil {
2270 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002271 log.Fields{"device-id": dh.deviceID, "err": err})
2272 }
mpagenko900ee4b2020-10-12 11:56:34 +00002273}
2274
dbainbri4d3a0dc2020-12-02 00:33:42 +00002275func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002276 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002277 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002278 // attention: the device reason update is done based on ONU-UNI-Port related activity
2279 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002280 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002281 // 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 +00002282 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302283 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002284 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002286 }
2287 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002289 // attention: the device reason update is done based on ONU-UNI-Port related activity
2290 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002291 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002292 // 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 +00002293 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002294 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002295 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302296}
2297
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2299 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002300 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302301 // attention: the device reason update is done based on ONU-UNI-Port related activity
2302 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302303
mpagenkof1fc3862021-02-16 10:09:52 +00002304 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002305 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002306 // which may be the case from some previous actvity on another UNI Port of the ONU
2307 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002308 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2309 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002310 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002311 }
2312 }
2313 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002314 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002315 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002317 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302318 }
mpagenkof1fc3862021-02-16 10:09:52 +00002319
2320 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2321 //events that request KvStore write
2322 if err := dh.storePersistentData(ctx); err != nil {
2323 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2324 log.Fields{"device-id": dh.deviceID, "err": err})
2325 }
2326 } else {
2327 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2328 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002329 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302330}
2331
Himani Chawla6d2ae152020-09-02 13:11:20 +05302332//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302334 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002335 case MibDatabaseSync:
2336 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002338 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002339 case UniLockStateDone:
2340 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002342 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002343 case MibDownloadDone:
2344 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002345 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002346 }
2347 case UniUnlockStateDone:
2348 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002350 }
mpagenko900ee4b2020-10-12 11:56:34 +00002351 case UniEnableStateDone:
2352 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002354 }
2355 case UniDisableStateDone:
2356 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002357 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002358 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002359 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002360 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002362 }
mpagenkof1fc3862021-02-16 10:09:52 +00002363 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002364 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002365 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002366 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002367 case OmciOnuSwUpgradeDone:
2368 {
2369 dh.upgradeSuccess = true
2370 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002371 default:
2372 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002373 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002374 }
2375 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002376}
2377
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002379 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302381 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002382 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002384 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302385 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002387 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002388 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002389 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002390 //store UniPort with the System-PortNumber key
2391 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002392 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002393 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2395 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002396 } //error logging already within UniPort method
2397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002399 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002400 }
2401 }
2402}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002403
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002404func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2405 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2406 if pDevEntry == nil {
2407 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2408 return
2409 }
2410 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2411 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2412 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2413 for _, mgmtEntityID := range pptpInstKeys {
2414 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2415 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2416 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2417 i++
2418 }
2419 } else {
2420 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2421 }
2422 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2423 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2424 for _, mgmtEntityID := range veipInstKeys {
2425 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2426 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2427 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2428 i++
2429 }
2430 } else {
2431 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2432 }
2433 if i == 0 {
2434 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2435 }
2436}
2437
mpagenko3af1f032020-06-10 08:53:41 +00002438// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002439func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002440 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302441 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002442 // with following remark:
2443 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2444 // # load on the core
2445
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002446 // 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 +00002447
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002448 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002449 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302450 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002451 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302452 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002453 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002454 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 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 +00002456 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002458 }
mpagenko3af1f032020-06-10 08:53:41 +00002459 }
2460 }
2461}
2462
2463// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002465 // compare enableUniPortStateUpdate() above
2466 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2467 for uniNo, uniPort := range dh.uniEntityMap {
2468 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302469 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002470 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302471 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002472 if !dh.isReconciling() {
2473 //maybe also use getter functions on uniPort - perhaps later ...
2474 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2475 } else {
2476 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2477 }
2478
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002479 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002480 }
2481}
2482
2483// ONU_Active/Inactive announcement on system KAFKA bus
2484// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002486 var de voltha.DeviceEvent
2487 eventContext := make(map[string]string)
2488 //Populating event context
2489 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002491 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302493 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002494 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 +00002495 }
2496 oltSerialNumber := parentDevice.SerialNumber
2497
2498 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2499 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2500 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302501 eventContext["olt-serial-number"] = oltSerialNumber
2502 eventContext["device-id"] = aDeviceID
2503 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002504 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002505 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002506
2507 /* Populating device event body */
2508 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302509 de.ResourceId = aDeviceID
2510 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002511 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2512 de.Description = fmt.Sprintf("%s Event - %s - %s",
2513 cEventObjectType, cOnuActivatedEvent, "Raised")
2514 } else {
2515 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2516 de.Description = fmt.Sprintf("%s Event - %s - %s",
2517 cEventObjectType, cOnuActivatedEvent, "Cleared")
2518 }
2519 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2521 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302522 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002523 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302525 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002526}
2527
Himani Chawla4d908332020-08-31 12:30:20 +05302528// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002530 chLSFsm := make(chan Message, 2048)
2531 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302532 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002534 sFsmName = "LockStateFSM"
2535 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002537 sFsmName = "UnLockStateFSM"
2538 }
mpagenko3af1f032020-06-10 08:53:41 +00002539
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002541 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002543 return
2544 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002546 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002547 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302548 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002549 dh.pLockStateFsm = pLSFsm
2550 } else {
2551 dh.pUnlockStateFsm = pLSFsm
2552 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002554 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002555 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002556 }
2557}
2558
2559// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002560func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002561 /* Uni Port lock/unlock procedure -
2562 ***** should run via 'adminDone' state and generate the argument requested event *****
2563 */
2564 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302565 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002566 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2567 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2568 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002569 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302570 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002571 }
2572 } else {
2573 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2574 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2575 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002576 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302577 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002578 }
2579 }
2580 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002581 if pLSStatemachine.Is(uniStDisabled) {
2582 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002583 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002584 // maybe try a FSM reset and then again ... - TODO!!!
2585 } else {
2586 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002587 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002588 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002589 }
2590 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002591 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002592 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002593 // maybe try a FSM reset and then again ... - TODO!!!
2594 }
2595 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002596 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002597 // maybe try a FSM reset and then again ... - TODO!!!
2598 }
2599}
2600
mpagenko80622a52021-02-09 16:53:23 +00002601// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002602func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002603 //in here lockUpgradeFsm is already locked
2604 chUpgradeFsm := make(chan Message, 2048)
2605 var sFsmName = "OnuSwUpgradeFSM"
2606 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002607 if apDevEntry.PDevOmciCC == nil {
2608 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2609 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002610 }
mpagenko15ff4a52021-03-02 10:09:20 +00002611 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002612 sFsmName, chUpgradeFsm)
2613 if dh.pOnuUpradeFsm != nil {
2614 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2615 if pUpgradeStatemachine != nil {
2616 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002617 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002618 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2619 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2620 // maybe try a FSM reset and then again ... - TODO!!!
2621 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2622 }
2623 /***** LockStateFSM started */
2624 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2625 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2626 } else {
2627 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2628 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2629 // maybe try a FSM reset and then again ... - TODO!!!
2630 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2631 }
2632 } else {
2633 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2634 // maybe try a FSM reset and then again ... - TODO!!!
2635 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2636 }
2637 } else {
2638 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2639 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2640 }
2641 return nil
2642}
2643
2644// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2645func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2646 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2647 "device-id": dh.deviceID})
2648 dh.lockUpgradeFsm.Lock()
2649 defer dh.lockUpgradeFsm.Unlock()
2650 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2651}
2652
mpagenko15ff4a52021-03-02 10:09:20 +00002653// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2654func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2655 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2656 if pDevEntry == nil {
2657 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2658 return
2659 }
2660
2661 dh.lockUpgradeFsm.RLock()
2662 defer dh.lockUpgradeFsm.RUnlock()
2663 if dh.pOnuUpradeFsm != nil {
2664 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2665 if pUpgradeStatemachine != nil {
2666 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2667 // (some manual forced commit could do without)
2668 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko183647c2021-06-08 15:25:04 +00002669 // here no need to update the upgrade image state to activated as the state will be immediately be set to committing
mpagenko59498c12021-03-18 14:15:15 +00002670 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002671 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2672 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2673 return
2674 }
2675 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2676 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2677 } else {
2678 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2679 log.Fields{"device-id": dh.deviceID})
2680 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2681 return
2682 }
mpagenko183647c2021-06-08 15:25:04 +00002683 } else {
2684 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2685 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2686 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2687 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2688 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2689 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2690 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2691 }
2692 }
mpagenko15ff4a52021-03-02 10:09:20 +00002693 }
2694 }
2695 } else {
2696 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2697 }
2698}
2699
Himani Chawla6d2ae152020-09-02 13:11:20 +05302700//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002701func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002702
2703 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002704 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002705 kvbackend := &db.Backend{
2706 Client: dh.pOpenOnuAc.kvClient,
2707 StoreType: dh.pOpenOnuAc.KVStoreType,
2708 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002709 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002710 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2711 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002712
mpagenkoaf801632020-07-03 10:00:42 +00002713 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002714}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002715func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302716 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002717
mpagenkodff5dda2020-08-28 11:52:01 +00002718 for _, field := range flow.GetOfbFields(apFlowItem) {
2719 switch field.Type {
2720 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2721 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002722 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002723 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2724 }
mpagenko01e726e2020-10-23 09:45:29 +00002725 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002726 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2727 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302728 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002729 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302730 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2731 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002732 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2733 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002734 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2735 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302736 return
mpagenkodff5dda2020-08-28 11:52:01 +00002737 }
2738 }
mpagenko01e726e2020-10-23 09:45:29 +00002739 */
mpagenkodff5dda2020-08-28 11:52:01 +00002740 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2741 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302742 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002743 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302744 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002745 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302746 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002747 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002748 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302749 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002750 }
2751 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2752 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302753 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002755 "PCP": loAddPcp})
2756 }
2757 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2758 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002759 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002760 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2761 }
2762 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2763 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002764 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002765 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2766 }
2767 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2768 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002769 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002770 "IPv4-DST": field.GetIpv4Dst()})
2771 }
2772 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2773 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002774 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002775 "IPv4-SRC": field.GetIpv4Src()})
2776 }
2777 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2778 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002779 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002780 "Metadata": field.GetTableMetadata()})
2781 }
2782 /*
2783 default:
2784 {
2785 //all other entires ignored
2786 }
2787 */
2788 }
2789 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302790}
mpagenkodff5dda2020-08-28 11:52:01 +00002791
dbainbri4d3a0dc2020-12-02 00:33:42 +00002792func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002793 for _, action := range flow.GetActions(apFlowItem) {
2794 switch action.Type {
2795 /* not used:
2796 case of.OfpActionType_OFPAT_OUTPUT:
2797 {
mpagenko01e726e2020-10-23 09:45:29 +00002798 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002799 "Output": action.GetOutput()})
2800 }
2801 */
2802 case of.OfpActionType_OFPAT_PUSH_VLAN:
2803 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002805 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2806 }
2807 case of.OfpActionType_OFPAT_SET_FIELD:
2808 {
2809 pActionSetField := action.GetSetField()
2810 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002812 "OxcmClass": pActionSetField.Field.OxmClass})
2813 }
2814 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302815 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002816 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302817 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002818 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302819 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002820 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302821 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002822 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002823 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002824 "Type": pActionSetField.Field.GetOfbField().Type})
2825 }
2826 }
2827 /*
2828 default:
2829 {
2830 //all other entires ignored
2831 }
2832 */
2833 }
2834 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302835}
2836
2837//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002838func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302839 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2840 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2841 var loAddPcp, loSetPcp uint8
2842 var loIPProto uint32
2843 /* the TechProfileId is part of the flow Metadata - compare also comment within
2844 * OLT-Adapter:openolt_flowmgr.go
2845 * Metadata 8 bytes:
2846 * Most Significant 2 Bytes = Inner VLAN
2847 * Next 2 Bytes = Tech Profile ID(TPID)
2848 * Least Significant 4 Bytes = Port ID
2849 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2850 * subscriber related flows.
2851 */
2852
dbainbri4d3a0dc2020-12-02 00:33:42 +00002853 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302854 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002855 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302856 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002857 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302858 }
mpagenko551a4d42020-12-08 18:09:20 +00002859 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002860 loCookie := apFlowItem.GetCookie()
2861 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002862 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002863 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302864
dbainbri4d3a0dc2020-12-02 00:33:42 +00002865 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002866 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302867 if loIPProto == 2 {
2868 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2869 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002870 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2871 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302872 return nil
2873 }
mpagenko01e726e2020-10-23 09:45:29 +00002874 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002875 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002876
2877 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002878 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002879 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2880 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2881 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2882 //TODO!!: Use DeviceId within the error response to rwCore
2883 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002884 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002885 }
2886 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002888 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2889 } else {
2890 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2891 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2892 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302893 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002894 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002895 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002896 }
mpagenko9a304ea2020-12-16 15:54:01 +00002897
2898 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002899 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002900 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302901 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002902 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002903 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002904 dh.lockVlanConfig.RUnlock()
2905 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002906 }
mpagenkof1fc3862021-02-16 10:09:52 +00002907 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002908 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002909 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002910}
2911
2912//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002913func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002914 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2915 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2916 //no extra check is done on the rule parameters
2917 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2918 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2919 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2920 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002921 // - 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 +00002922 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002923 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002924
2925 /* TT related temporary workaround - should not be needed anymore
2926 for _, field := range flow.GetOfbFields(apFlowItem) {
2927 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2928 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002929 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002930 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2931 if loIPProto == 2 {
2932 // 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 +00002933 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002934 log.Fields{"device-id": dh.deviceID})
2935 return nil
2936 }
2937 }
2938 } //for all OfbFields
2939 */
2940
mpagenko9a304ea2020-12-16 15:54:01 +00002941 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002942 dh.lockVlanConfig.RLock()
2943 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002944 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002946 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002947 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002948 log.Fields{"device-id": dh.deviceID})
2949 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002950 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002951 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002952
mpagenko01e726e2020-10-23 09:45:29 +00002953 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002954}
2955
Himani Chawla26e555c2020-08-31 12:30:20 +05302956// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002957// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002958func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002959 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002960 chVlanFilterFsm := make(chan Message, 2048)
2961
dbainbri4d3a0dc2020-12-02 00:33:42 +00002962 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002963 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002964 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302965 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002966 }
2967
dbainbri4d3a0dc2020-12-02 00:33:42 +00002968 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002969 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002970 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002971 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002972 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002973 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2974 // (from parallel processing)
2975 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302976 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002977 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2978 if pVlanFilterStatemachine != nil {
2979 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2980 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002981 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302982 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002983 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302984 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002985 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302986 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2987 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002988 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002989 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002990 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302991 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002992 }
2993 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002994 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002995 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302996 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002997 }
2998 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002999 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003000 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303001 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003002 }
3003 return nil
3004}
3005
mpagenkofc4f56e2020-11-04 17:17:49 +00003006//VerifyVlanConfigRequest checks on existence of a given uniPort
3007// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003008func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003009 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3010 var pCurrentUniPort *onuUniPort
3011 for _, uniPort := range dh.uniEntityMap {
3012 // only if this port is validated for operState transfer
3013 if uniPort.uniID == uint8(aUniID) {
3014 pCurrentUniPort = uniPort
3015 break //found - end search loop
3016 }
3017 }
3018 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003019 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003020 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3021 return
3022 }
mpagenko551a4d42020-12-08 18:09:20 +00003023 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003024}
3025
mpagenkodff5dda2020-08-28 11:52:01 +00003026//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003027func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003028 //TODO!! verify and start pending flow configuration
3029 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3030 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003031
3032 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303033 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003034 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003035 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3036 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3037 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003038 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3039 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3040 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3041 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3042 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3043 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3044 } else {
3045 /***** UniVlanConfigFsm continued */
3046 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3047 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3048 "UniPort": apUniPort.portNo})
3049 }
3050 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3051 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3052 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3053 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3054 } else {
3055 /***** UniVlanConfigFsm continued */
3056 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3057 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3058 "UniPort": apUniPort.portNo})
3059 }
mpagenkodff5dda2020-08-28 11:52:01 +00003060 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003061 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3062 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003063 "UniPort": apUniPort.portNo})
3064 }
3065 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003066 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3067 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3068 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003069 }
3070 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003071 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003072 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003073 }
mpagenkof1fc3862021-02-16 10:09:52 +00003074 } else {
3075 dh.lockVlanConfig.RUnlock()
3076 }
mpagenkodff5dda2020-08-28 11:52:01 +00003077}
3078
3079//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3080// 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 +00003081func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3082 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003083 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3084 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003085 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303086 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003087 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003088}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003089
mpagenkof1fc3862021-02-16 10:09:52 +00003090//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3091func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3092 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3093 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3094 // obviously then parallel processing on the cancel must be avoided
3095 // deadline context to ensure completion of background routines waited for
3096 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3097 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3098 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3099
3100 aPDevEntry.resetKvProcessingErrorIndication()
3101 var wg sync.WaitGroup
3102 wg.Add(1) // for the 1 go routine to finish
3103
3104 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3105 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3106
3107 return aPDevEntry.getKvProcessingErrorIndication()
3108}
3109
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003110//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3111//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003112func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3113 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003114
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003115 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003116 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003117 return nil
3118 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003119 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003120
dbainbri4d3a0dc2020-12-02 00:33:42 +00003121 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003122 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003124 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3125 }
3126 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3127
mpagenkof1fc3862021-02-16 10:09:52 +00003128 if aWriteToKvStore {
3129 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3130 }
3131 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003132}
3133
dbainbri4d3a0dc2020-12-02 00:33:42 +00003134func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003135 defer cancel() //ensure termination of context (may be pro forma)
3136 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003137 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003138 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003139}
3140
dbainbri4d3a0dc2020-12-02 00:33:42 +00003141func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003142
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003143 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003144 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003145 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003146 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3147 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003148 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003149 return err
3150 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003151 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003152 return nil
3153 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003154 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003155 return nil
3156}
3157
dbainbri4d3a0dc2020-12-02 00:33:42 +00003158func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3159 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003160 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003161 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003162 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3163 }
mpagenkof1fc3862021-02-16 10:09:52 +00003164 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003165}
3166
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003167func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3168 var errStr string = ""
3169 for _, err := range errS {
3170 if err != nil {
3171 errStr = errStr + err.Error() + " "
3172 }
3173 }
3174 if errStr != "" {
3175 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3176 }
3177 return nil
3178}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003179
3180// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
3181func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3182 dh.lockDevice.RLock()
3183 defer dh.lockDevice.RUnlock()
3184 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3185 return uniPort.entityID, nil
3186 }
3187 return 0, errors.New("error-fetching-uni-port")
3188}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003189
3190// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003191func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3192 var errorsList []error
3193 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 -08003194
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003195 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3196 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3197 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3198
3199 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3200 // successfully.
3201 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3202 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3203 if len(errorsList) > 0 {
3204 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3205 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003206 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003207 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3208 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003209}
3210
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003211func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3212 var err error
3213 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003214 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003215
3216 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3217 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3218 errorsList = append(errorsList, err)
3219 }
3220 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003221 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003222
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003223 return errorsList
3224}
3225
3226func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3227 var err error
3228 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003229 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003230 // Check if group metric related config is updated
3231 for _, v := range pmConfigs.Groups {
3232 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3233 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3234 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3235
3236 if ok && m.frequency != v.GroupFreq {
3237 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3238 errorsList = append(errorsList, err)
3239 }
3240 }
3241 if ok && m.enabled != v.Enabled {
3242 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3243 errorsList = append(errorsList, err)
3244 }
3245 }
3246 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003247 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003248 return errorsList
3249}
3250
3251func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3252 var err error
3253 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003254 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003255 // Check if standalone metric related config is updated
3256 for _, v := range pmConfigs.Metrics {
3257 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003258 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003259 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3260
3261 if ok && m.frequency != v.SampleFreq {
3262 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3263 errorsList = append(errorsList, err)
3264 }
3265 }
3266 if ok && m.enabled != v.Enabled {
3267 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3268 errorsList = append(errorsList, err)
3269 }
3270 }
3271 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003272 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003273 return errorsList
3274}
3275
3276// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003277func (dh *deviceHandler) startCollector(ctx context.Context) {
3278 logger.Debugf(ctx, "startingCollector")
3279
3280 // Start routine to process OMCI GET Responses
3281 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003282 // Initialize the next metric collection time.
3283 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3284 // reset like onu rebooted.
3285 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003286 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003287 for {
3288 select {
3289 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003290 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003291 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003292 // Stop the L2 PM FSM
3293 go func() {
3294 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3295 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3296 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3297 }
3298 } else {
3299 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3300 }
3301 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003302 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3303 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3304 }
3305 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3306 dh.pOnuMetricsMgr.stopTicks <- true
3307 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003308
Girish Gowdrae09a6202021-01-12 18:10:59 -08003309 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003310 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3311 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3312 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3313 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3314 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003315 // Update the next metric collection time.
3316 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003317 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003318 } else {
3319 if dh.pmConfigs.Grouped { // metrics are managed as a group
3320 // parse through the group and standalone metrics to see it is time to collect their metrics
3321 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003322
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003323 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3324 // 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 -08003325 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3326 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003327 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3328 }
3329 }
3330 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3331 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3332 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3333 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3334 }
3335 }
3336 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3337
3338 // parse through the group and update the next metric collection time
3339 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3340 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3341 // 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 -08003342 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3343 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003344 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3345 }
3346 }
3347 // parse through the standalone metrics and update the next metric collection time
3348 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3349 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3350 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3351 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3352 }
3353 }
3354 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3355 } /* else { // metrics are not managed as a group
3356 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3357 } */
3358 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003359 }
3360 }
3361}
kesavandfdf77632021-01-26 23:40:33 -05003362
3363func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3364
3365 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3366 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3367}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003368
mpagenkof1fc3862021-02-16 10:09:52 +00003369func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3370 if pFsm == nil {
3371 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003372 }
mpagenkof1fc3862021-02-16 10:09:52 +00003373 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003374}
3375
mpagenkof1fc3862021-02-16 10:09:52 +00003376func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3377 var pFsm *fsm.FSM
3378 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3379 switch omciFsm {
3380 case cUploadFsm:
3381 {
3382 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3383 }
3384 case cDownloadFsm:
3385 {
3386 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3387 }
3388 case cUniLockFsm:
3389 {
3390 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3391 }
3392 case cUniUnLockFsm:
3393 {
3394 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3395 }
3396 case cL2PmFsm:
3397 {
3398 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3399 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3400 } else {
3401 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003402 }
3403 }
mpagenko80622a52021-02-09 16:53:23 +00003404 case cOnuUpgradeFsm:
3405 {
3406 dh.lockUpgradeFsm.RLock()
3407 defer dh.lockUpgradeFsm.RUnlock()
3408 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3409 }
mpagenkof1fc3862021-02-16 10:09:52 +00003410 default:
3411 {
3412 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3413 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3414 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003415 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003416 }
mpagenkof1fc3862021-02-16 10:09:52 +00003417 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003418}
3419
mpagenkof1fc3862021-02-16 10:09:52 +00003420func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3421 for _, v := range dh.pOnuTP.pAniConfigFsm {
3422 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003423 return false
3424 }
3425 }
3426 return true
3427}
3428
mpagenkof1fc3862021-02-16 10:09:52 +00003429func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3430 dh.lockVlanConfig.RLock()
3431 defer dh.lockVlanConfig.RUnlock()
3432 for _, v := range dh.UniVlanConfigFsmMap {
3433 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3434 return false
3435 }
3436 }
3437 return true //FSM not active - so there is no activity on omci
3438}
3439
3440func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3441 dh.lockVlanConfig.RLock()
3442 defer dh.lockVlanConfig.RUnlock()
3443 for _, v := range dh.UniVlanConfigFsmMap {
3444 if v.pAdaptFsm.pFsm != nil {
3445 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3446 return true //there is at least one VLAN FSM with some active configuration
3447 }
3448 }
3449 }
3450 return false //there is no VLAN FSM with some active configuration
3451}
3452
3453func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3454 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3455 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3456 return false
3457 }
3458 }
3459 // a further check is done to identify, if at least some data traffic related configuration exists
3460 // 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])
3461 return dh.checkUserServiceExists(ctx)
3462}
3463
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003464func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3465 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3466 if err := dh.resetFsms(ctx, false); err != nil {
3467 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3468 // TODO: fatal error reset ONU, delete deviceHandler!
3469 return
3470 }
3471 if !dh.getCollectorIsRunning() {
3472 // Start PM collector routine
3473 go dh.startCollector(ctx)
3474 }
Himani Chawla1472c682021-03-17 17:11:14 +05303475 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303476 go dh.startAlarmManager(ctx)
3477 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003478 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003479 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003480}
3481
3482func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3483 dh.mutexCollectorFlag.Lock()
3484 dh.collectorIsRunning = flagValue
3485 dh.mutexCollectorFlag.Unlock()
3486}
3487
3488func (dh *deviceHandler) getCollectorIsRunning() bool {
3489 dh.mutexCollectorFlag.RLock()
3490 flagValue := dh.collectorIsRunning
3491 dh.mutexCollectorFlag.RUnlock()
3492 return flagValue
3493}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303494
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303495func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3496 dh.mutextAlarmManagerFlag.Lock()
3497 dh.alarmManagerIsRunning = flagValue
3498 dh.mutextAlarmManagerFlag.Unlock()
3499}
3500
Himani Chawla1472c682021-03-17 17:11:14 +05303501func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303502 dh.mutextAlarmManagerFlag.RLock()
3503 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303504 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303505 dh.mutextAlarmManagerFlag.RUnlock()
3506 return flagValue
3507}
3508
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303509func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3510 logger.Debugf(ctx, "startingAlarmManager")
3511
3512 // Start routine to process OMCI GET Responses
3513 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303514 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303515 if stop := <-dh.stopAlarmManager; stop {
3516 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303517 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303518 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303519 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3520 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3521 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303522 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303523 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303524 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3525 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303526 }
3527}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003528
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003529func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003530 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003531
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003532 if !dh.isReconciling() {
3533 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003534 logger.Debugw(ctx, "wait for channel signal or timeout",
3535 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003536 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003537 case success := <-dh.chReconcilingFinished:
3538 if success {
Maninderb5187552021-03-23 22:23:42 +05303539 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3540 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3541 log.Fields{"device-id": dh.deviceID})
3542 } else {
3543 connectStatus := voltha.ConnectStatus_UNREACHABLE
3544 operState := voltha.OperStatus_UNKNOWN
3545 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3546 connectStatus = voltha.ConnectStatus_REACHABLE
3547 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3548 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3549 operState = voltha.OperStatus_ACTIVE
3550 } else {
3551 operState = voltha.OperStatus_ACTIVATING
3552 }
3553 }
3554 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3555 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3556 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3557 operState = voltha.OperStatus_DISCOVERED
3558 }
3559
3560 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
3561 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3562 logger.Errorw(ctx, "unable to update device state to core",
3563 log.Fields{"OperState": onuDevEntry.sOnuPersistentData.PersOperState, "Err": err})
3564 }
3565 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003566 logger.Debugw(ctx, "reconciling has been finished in time",
3567 log.Fields{"device-id": dh.deviceID})
3568 } else {
Maninderb5187552021-03-23 22:23:42 +05303569 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003570 log.Fields{"device-id": dh.deviceID})
3571 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003572 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Maninderb5187552021-03-23 22:23:42 +05303573 //TODO: handle notification to core if reconciling timed out
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003574 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3575 log.Fields{"device-id": dh.deviceID})
3576 }
3577 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003578 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003579 dh.mutexReconcilingFlag.Unlock()
3580 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003581 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003582 dh.mutexReconcilingFlag.Lock()
3583 if skipOnuConfig {
3584 dh.reconciling = cSkipOnuConfigReconciling
3585 } else {
3586 dh.reconciling = cOnuConfigReconciling
3587 }
3588 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003589}
3590
3591func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3592 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3593 if dh.isReconciling() {
3594 dh.chReconcilingFinished <- true
3595 } else {
3596 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3597 }
3598}
3599
3600func (dh *deviceHandler) isReconciling() bool {
3601 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003602 defer dh.mutexReconcilingFlag.RUnlock()
3603 return dh.reconciling != cNoReconciling
3604}
3605
3606func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3607 dh.mutexReconcilingFlag.RLock()
3608 defer dh.mutexReconcilingFlag.RUnlock()
3609 return dh.reconciling == cSkipOnuConfigReconciling
3610}
3611
3612func (dh *deviceHandler) setDeviceReason(value uint8) {
3613 dh.mutexDeviceReason.Lock()
3614 dh.deviceReason = value
3615 dh.mutexDeviceReason.Unlock()
3616}
3617
3618func (dh *deviceHandler) getDeviceReason() uint8 {
3619 dh.mutexDeviceReason.RLock()
3620 value := dh.deviceReason
3621 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003622 return value
3623}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003624
3625func (dh *deviceHandler) getDeviceReasonString() string {
3626 return deviceReasonMap[dh.getDeviceReason()]
3627}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003628
3629func (dh *deviceHandler) setReconcilingFlows(value bool) {
3630 dh.mutexReconcilingFlowsFlag.Lock()
3631 dh.reconcilingFlows = value
3632 dh.mutexReconcilingFlowsFlag.Unlock()
3633}
3634
3635func (dh *deviceHandler) isReconcilingFlows() bool {
3636 dh.mutexReconcilingFlowsFlag.RLock()
3637 value := dh.reconcilingFlows
3638 dh.mutexReconcilingFlowsFlag.RUnlock()
3639 return value
3640}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003641
3642func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3643 dh.mutexReadyForOmciConfig.Lock()
3644 dh.readyForOmciConfig = flagValue
3645 dh.mutexReadyForOmciConfig.Unlock()
3646}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003647func (dh *deviceHandler) isReadyForOmciConfig() bool {
3648 dh.mutexReadyForOmciConfig.RLock()
3649 flagValue := dh.readyForOmciConfig
3650 dh.mutexReadyForOmciConfig.RUnlock()
3651 return flagValue
3652}