blob: 1a541c7973135ac2d19dcfa517abbb612f88c2c2 [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
mpagenko7455fd42021-06-10 16:25:55 +00001366 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001367 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 }
1901 return nil
1902}
1903
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001905 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001906 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001907 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001909
mpagenko900ee4b2020-10-12 11:56:34 +00001910 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1911 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1912 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001913 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001915 log.Fields{"device-id": dh.deviceID, "error": err})
1916 // abort: system behavior is just unstable ...
1917 return err
1918 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001919 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 _ = 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 +00001921
1922 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1923 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1924 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001926 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001928 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001929 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001931
1932 //TODO!!! remove existing traffic profiles
1933 /* from py code, if TP's exist, remove them - not yet implemented
1934 self._tp = dict()
1935 # Let TP download happen again
1936 for uni_id in self._tp_service_specific_task:
1937 self._tp_service_specific_task[uni_id].clear()
1938 for uni_id in self._tech_profile_download_done:
1939 self._tech_profile_download_done[uni_id].clear()
1940 */
1941
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001943
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001944 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001945
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001947 // abort: system behavior is just unstable ...
1948 return err
1949 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001951 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001953 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001954 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001956 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001957 // abort: system behavior is just unstable ...
1958 return err
1959 }
1960 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001962 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001963 return nil
1964}
1965
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001966func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001967 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1968 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1969 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1970 // and using the stop/reset event should never harm
1971
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001973 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001975 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1976 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001977 if pDevEntry.PDevOmciCC != nil {
1978 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1979 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001980 pDevEntry.mutexOnuImageStatus.RLock()
1981 if pDevEntry.pOnuImageStatus != nil {
1982 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
1983 }
1984 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001985
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001986 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001987 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001988 }
1989 //MibDownload may run
1990 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1991 if pMibDlFsm != nil {
1992 _ = pMibDlFsm.Event(dlEvReset)
1993 }
1994 //port lock/unlock FSM's may be active
1995 if dh.pUnlockStateFsm != nil {
1996 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1997 }
1998 if dh.pLockStateFsm != nil {
1999 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2000 }
2001 //techProfile related PonAniConfigFsm FSM may be active
2002 if dh.pOnuTP != nil {
2003 // should always be the case here
2004 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2005 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002006 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002007 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002008 }
mpagenko900ee4b2020-10-12 11:56:34 +00002009 }
2010 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002011 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002012 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002013 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2014 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002015 dh.lockVlanConfig.RUnlock()
2016 //reset of all Fsm is always accompanied by global persistency data removal
2017 // no need to remove specific data
2018 pVlanFilterFsm.RequestClearPersistency(false)
2019 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002020 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002021 } else {
2022 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002023 }
2024 }
2025 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002026 if dh.getCollectorIsRunning() {
2027 // Stop collector routine
2028 dh.stopCollector <- true
2029 }
Himani Chawla1472c682021-03-17 17:11:14 +05302030 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302031 dh.stopAlarmManager <- true
2032 }
2033
mpagenko80622a52021-02-09 16:53:23 +00002034 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002035 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002036 dh.lockUpgradeFsm.RLock()
2037 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002038 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002039 }
2040 dh.lockUpgradeFsm.RUnlock()
2041
mpagenko7d6bb022021-03-11 15:07:55 +00002042 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002043 return nil
2044}
2045
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2047 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 +05302048
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002049 // store persistent data collected during MIB upload processing
2050 if err := dh.storePersistentData(ctx); err != nil {
2051 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2052 log.Fields{"device-id": dh.deviceID, "err": err})
2053 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002054 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002055 dh.addAllUniPorts(ctx)
2056
mpagenkoa40e99a2020-11-17 13:50:39 +00002057 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2058 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2059 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2060 * disable/enable toggling here to allow traffic
2061 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2062 * like the py comment says:
2063 * # start by locking all the unis till mib sync and initial mib is downloaded
2064 * # this way we can capture the port down/up events when we are ready
2065 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302066
mpagenkoa40e99a2020-11-17 13:50:39 +00002067 // Init Uni Ports to Admin locked state
2068 // *** should generate UniLockStateDone event *****
2069 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002071 } else { //LockStateFSM already init
2072 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002074 }
2075}
2076
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2078 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302079 /* Mib download procedure -
2080 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2081 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002083 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002084 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002085 return
2086 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302087 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2088 if pMibDlFsm != nil {
2089 if pMibDlFsm.Is(dlStDisabled) {
2090 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 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 +05302092 // maybe try a FSM reset and then again ... - TODO!!!
2093 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002094 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302095 // maybe use more specific states here for the specific download steps ...
2096 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002097 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302098 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002099 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302100 //Begin MIB data download (running autonomously)
2101 }
2102 }
2103 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002105 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302106 // maybe try a FSM reset and then again ... - TODO!!!
2107 }
2108 /***** Mib download started */
2109 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002110 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302111 }
2112}
2113
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2115 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302116 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002117 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002118 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002119 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002120 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2121 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2122 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2123 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2126 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302128 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302130 }
2131 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302133 log.Fields{"device-id": dh.deviceID})
2134 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002135 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002136
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002137 if !dh.getCollectorIsRunning() {
2138 // Start PM collector routine
2139 go dh.startCollector(ctx)
2140 }
2141 if !dh.getAlarmManagerIsRunning(ctx) {
2142 go dh.startAlarmManager(ctx)
2143 }
2144
Girish Gowdrae0140f02021-02-02 16:55:09 -08002145 // Initialize classical L2 PM Interval Counters
2146 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2147 // There is no way we should be landing here, but if we do then
2148 // there is nothing much we can do about this other than log error
2149 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2150 }
2151
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002152 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002153
2154 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2155 if pDevEntry == nil {
2156 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2157 return
2158 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002159 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002160 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002161 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002162 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2163 log.Fields{"device-id": dh.deviceID})
2164 go dh.reconcileDeviceTechProf(ctx)
2165 // reconcilement will be continued after ani config is done
2166 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002167 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002168 // *** should generate UniUnlockStateDone event *****
2169 if dh.pUnlockStateFsm == nil {
2170 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2171 } else { //UnlockStateFSM already init
2172 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2173 dh.runUniLockFsm(ctx, false)
2174 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 }
2176}
2177
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2179 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302180
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002181 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002183 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2185 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002186 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002188 return
2189 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002190 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002191 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002192 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 if err := dh.storePersistentData(ctx); err != nil {
2194 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002195 log.Fields{"device-id": dh.deviceID, "err": err})
2196 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302197 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 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 +05302199 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002201 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302202 }
2203}
2204
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2206 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002207 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002209 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2210 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002212 }
2213
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002215 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002217
2218 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002220
dbainbri4d3a0dc2020-12-02 00:33:42 +00002221 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002222 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002224 return
2225 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002226 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002227 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002228 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 if err := dh.storePersistentData(ctx); err != nil {
2230 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002231 log.Fields{"device-id": dh.deviceID, "err": err})
2232 }
mpagenko900ee4b2020-10-12 11:56:34 +00002233}
2234
dbainbri4d3a0dc2020-12-02 00:33:42 +00002235func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2236 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002237 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002239 voltha.OperStatus_ACTIVE); err != nil {
2240 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002242 }
2243
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002245 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002246 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002248
2249 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002250 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002251
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002253 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002254 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002255 return
2256 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002257 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002258 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002259 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 if err := dh.storePersistentData(ctx); err != nil {
2261 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002262 log.Fields{"device-id": dh.deviceID, "err": err})
2263 }
mpagenko900ee4b2020-10-12 11:56:34 +00002264}
2265
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002267 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002269 // attention: the device reason update is done based on ONU-UNI-Port related activity
2270 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002271 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002272 // 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 +00002273 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302274 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002275 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002277 }
2278 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002279 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002280 // attention: the device reason update is done based on ONU-UNI-Port related activity
2281 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002282 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002283 // 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 +00002284 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002285 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002286 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302287}
2288
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2290 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002291 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302292 // attention: the device reason update is done based on ONU-UNI-Port related activity
2293 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302294
mpagenkof1fc3862021-02-16 10:09:52 +00002295 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002296 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002297 // which may be the case from some previous actvity on another UNI Port of the ONU
2298 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002299 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2300 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002301 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002302 }
2303 }
2304 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002305 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002306 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002308 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302309 }
mpagenkof1fc3862021-02-16 10:09:52 +00002310
2311 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2312 //events that request KvStore write
2313 if err := dh.storePersistentData(ctx); err != nil {
2314 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2315 log.Fields{"device-id": dh.deviceID, "err": err})
2316 }
2317 } else {
2318 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2319 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002320 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302321}
2322
Himani Chawla6d2ae152020-09-02 13:11:20 +05302323//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302325 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002326 case MibDatabaseSync:
2327 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002329 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002330 case UniLockStateDone:
2331 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002333 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002334 case MibDownloadDone:
2335 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002337 }
2338 case UniUnlockStateDone:
2339 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002341 }
mpagenko900ee4b2020-10-12 11:56:34 +00002342 case UniEnableStateDone:
2343 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002345 }
2346 case UniDisableStateDone:
2347 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002349 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002350 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002351 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002352 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002353 }
mpagenkof1fc3862021-02-16 10:09:52 +00002354 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002355 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002357 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002358 case OmciOnuSwUpgradeDone:
2359 {
2360 dh.upgradeSuccess = true
2361 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002362 default:
2363 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002365 }
2366 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002367}
2368
dbainbri4d3a0dc2020-12-02 00:33:42 +00002369func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002370 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002371 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302372 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002373 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002375 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302376 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002377 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002378 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002379 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002380 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002381 //store UniPort with the System-PortNumber key
2382 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002383 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002384 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002385 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2386 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002387 } //error logging already within UniPort method
2388 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002390 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002391 }
2392 }
2393}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002394
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002395func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2396 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2397 if pDevEntry == nil {
2398 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2399 return
2400 }
2401 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2402 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2403 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2404 for _, mgmtEntityID := range pptpInstKeys {
2405 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2406 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2407 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2408 i++
2409 }
2410 } else {
2411 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2412 }
2413 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2414 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2415 for _, mgmtEntityID := range veipInstKeys {
2416 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2417 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2418 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2419 i++
2420 }
2421 } else {
2422 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2423 }
2424 if i == 0 {
2425 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2426 }
2427}
2428
mpagenko3af1f032020-06-10 08:53:41 +00002429// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002431 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302432 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002433 // with following remark:
2434 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2435 // # load on the core
2436
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002437 // 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 +00002438
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002439 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002440 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002441 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002442 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302443 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002444 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002445 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002446 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 +00002447 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002448 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002449 }
mpagenko3af1f032020-06-10 08:53:41 +00002450 }
2451 }
2452}
2453
2454// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002456 // compare enableUniPortStateUpdate() above
2457 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2458 for uniNo, uniPort := range dh.uniEntityMap {
2459 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002460
2461 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002462 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302463 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002464 if !dh.isReconciling() {
2465 //maybe also use getter functions on uniPort - perhaps later ...
2466 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2467 } else {
2468 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2469 }
2470
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002471 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002472 }
2473}
2474
2475// ONU_Active/Inactive announcement on system KAFKA bus
2476// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002478 var de voltha.DeviceEvent
2479 eventContext := make(map[string]string)
2480 //Populating event context
2481 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002482 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002483 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002484 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302485 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002486 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 +00002487 }
2488 oltSerialNumber := parentDevice.SerialNumber
2489
2490 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2491 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2492 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302493 eventContext["olt-serial-number"] = oltSerialNumber
2494 eventContext["device-id"] = aDeviceID
2495 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002496 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2497 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2498 deviceEntry.mutexPersOnuConfig.RLock()
2499 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2500 deviceEntry.mutexPersOnuConfig.RUnlock()
2501 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2502 deviceEntry.mutexPersOnuConfig.RLock()
2503 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2504 deviceEntry.mutexPersOnuConfig.RUnlock()
2505 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2506 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2507 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2508 } else {
2509 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2510 log.Fields{"device-id": aDeviceID})
2511 return
2512 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002513
2514 /* Populating device event body */
2515 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302516 de.ResourceId = aDeviceID
2517 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002518 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2519 de.Description = fmt.Sprintf("%s Event - %s - %s",
2520 cEventObjectType, cOnuActivatedEvent, "Raised")
2521 } else {
2522 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2523 de.Description = fmt.Sprintf("%s Event - %s - %s",
2524 cEventObjectType, cOnuActivatedEvent, "Cleared")
2525 }
2526 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002527 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2528 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302529 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002530 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002531 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302532 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002533}
2534
Himani Chawla4d908332020-08-31 12:30:20 +05302535// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002537 chLSFsm := make(chan Message, 2048)
2538 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302539 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002541 sFsmName = "LockStateFSM"
2542 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002543 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002544 sFsmName = "UnLockStateFSM"
2545 }
mpagenko3af1f032020-06-10 08:53:41 +00002546
dbainbri4d3a0dc2020-12-02 00:33:42 +00002547 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002548 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002550 return
2551 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002553 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002554 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302555 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002556 dh.pLockStateFsm = pLSFsm
2557 } else {
2558 dh.pUnlockStateFsm = pLSFsm
2559 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002560 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002561 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002562 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002563 }
2564}
2565
2566// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002567func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002568 /* Uni Port lock/unlock procedure -
2569 ***** should run via 'adminDone' state and generate the argument requested event *****
2570 */
2571 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302572 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002573 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2574 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2575 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002576 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302577 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002578 }
2579 } else {
2580 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2581 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2582 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002583 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302584 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002585 }
2586 }
2587 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002588 if pLSStatemachine.Is(uniStDisabled) {
2589 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002591 // maybe try a FSM reset and then again ... - TODO!!!
2592 } else {
2593 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002595 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002596 }
2597 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002598 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002599 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002600 // maybe try a FSM reset and then again ... - TODO!!!
2601 }
2602 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002603 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002604 // maybe try a FSM reset and then again ... - TODO!!!
2605 }
2606}
2607
mpagenko80622a52021-02-09 16:53:23 +00002608// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002609func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002610 //in here lockUpgradeFsm is already locked
2611 chUpgradeFsm := make(chan Message, 2048)
2612 var sFsmName = "OnuSwUpgradeFSM"
2613 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002614 if apDevEntry.PDevOmciCC == nil {
2615 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2616 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002617 }
mpagenko15ff4a52021-03-02 10:09:20 +00002618 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002619 sFsmName, chUpgradeFsm)
2620 if dh.pOnuUpradeFsm != nil {
2621 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2622 if pUpgradeStatemachine != nil {
2623 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002624 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002625 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2626 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2627 // maybe try a FSM reset and then again ... - TODO!!!
2628 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2629 }
2630 /***** LockStateFSM started */
2631 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2632 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2633 } else {
2634 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2635 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2636 // maybe try a FSM reset and then again ... - TODO!!!
2637 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2638 }
2639 } else {
2640 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2641 // maybe try a FSM reset and then again ... - TODO!!!
2642 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2643 }
2644 } else {
2645 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2646 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2647 }
2648 return nil
2649}
2650
2651// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2652func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2653 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2654 "device-id": dh.deviceID})
2655 dh.lockUpgradeFsm.Lock()
2656 defer dh.lockUpgradeFsm.Unlock()
2657 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2658}
2659
mpagenko15ff4a52021-03-02 10:09:20 +00002660// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2661func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2662 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2663 if pDevEntry == nil {
2664 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2665 return
2666 }
2667
2668 dh.lockUpgradeFsm.RLock()
2669 defer dh.lockUpgradeFsm.RUnlock()
2670 if dh.pOnuUpradeFsm != nil {
2671 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2672 if pUpgradeStatemachine != nil {
2673 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2674 // (some manual forced commit could do without)
2675 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko183647c2021-06-08 15:25:04 +00002676 // 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 +00002677 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002678 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2679 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2680 return
2681 }
2682 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2683 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2684 } else {
2685 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2686 log.Fields{"device-id": dh.deviceID})
2687 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2688 return
2689 }
mpagenko183647c2021-06-08 15:25:04 +00002690 } else {
2691 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2692 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2693 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2694 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2695 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2696 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2697 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2698 }
2699 }
mpagenko15ff4a52021-03-02 10:09:20 +00002700 }
2701 }
2702 } else {
2703 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2704 }
2705}
2706
Himani Chawla6d2ae152020-09-02 13:11:20 +05302707//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002708func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002709
2710 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002711 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002712 kvbackend := &db.Backend{
2713 Client: dh.pOpenOnuAc.kvClient,
2714 StoreType: dh.pOpenOnuAc.KVStoreType,
2715 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002716 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002717 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2718 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002719
mpagenkoaf801632020-07-03 10:00:42 +00002720 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002721}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002722func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302723 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002724
mpagenkodff5dda2020-08-28 11:52:01 +00002725 for _, field := range flow.GetOfbFields(apFlowItem) {
2726 switch field.Type {
2727 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2728 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002729 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002730 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2731 }
mpagenko01e726e2020-10-23 09:45:29 +00002732 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002733 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2734 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302735 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002736 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302737 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2738 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002739 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2740 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002741 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2742 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302743 return
mpagenkodff5dda2020-08-28 11:52:01 +00002744 }
2745 }
mpagenko01e726e2020-10-23 09:45:29 +00002746 */
mpagenkodff5dda2020-08-28 11:52:01 +00002747 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2748 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302749 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002750 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302751 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002752 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302753 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002754 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002755 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302756 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002757 }
2758 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2759 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302760 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002761 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002762 "PCP": loAddPcp})
2763 }
2764 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2765 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002766 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002767 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2768 }
2769 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2770 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002771 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002772 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2773 }
2774 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2775 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002776 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002777 "IPv4-DST": field.GetIpv4Dst()})
2778 }
2779 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2780 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002781 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002782 "IPv4-SRC": field.GetIpv4Src()})
2783 }
2784 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2785 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002786 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002787 "Metadata": field.GetTableMetadata()})
2788 }
2789 /*
2790 default:
2791 {
2792 //all other entires ignored
2793 }
2794 */
2795 }
2796 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302797}
mpagenkodff5dda2020-08-28 11:52:01 +00002798
dbainbri4d3a0dc2020-12-02 00:33:42 +00002799func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002800 for _, action := range flow.GetActions(apFlowItem) {
2801 switch action.Type {
2802 /* not used:
2803 case of.OfpActionType_OFPAT_OUTPUT:
2804 {
mpagenko01e726e2020-10-23 09:45:29 +00002805 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002806 "Output": action.GetOutput()})
2807 }
2808 */
2809 case of.OfpActionType_OFPAT_PUSH_VLAN:
2810 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002812 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2813 }
2814 case of.OfpActionType_OFPAT_SET_FIELD:
2815 {
2816 pActionSetField := action.GetSetField()
2817 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002818 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002819 "OxcmClass": pActionSetField.Field.OxmClass})
2820 }
2821 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302822 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002823 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302824 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002825 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302826 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002827 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302828 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002829 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002830 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002831 "Type": pActionSetField.Field.GetOfbField().Type})
2832 }
2833 }
2834 /*
2835 default:
2836 {
2837 //all other entires ignored
2838 }
2839 */
2840 }
2841 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302842}
2843
2844//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002845func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302846 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2847 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2848 var loAddPcp, loSetPcp uint8
2849 var loIPProto uint32
2850 /* the TechProfileId is part of the flow Metadata - compare also comment within
2851 * OLT-Adapter:openolt_flowmgr.go
2852 * Metadata 8 bytes:
2853 * Most Significant 2 Bytes = Inner VLAN
2854 * Next 2 Bytes = Tech Profile ID(TPID)
2855 * Least Significant 4 Bytes = Port ID
2856 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2857 * subscriber related flows.
2858 */
2859
dbainbri4d3a0dc2020-12-02 00:33:42 +00002860 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302861 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002862 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302863 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002864 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302865 }
mpagenko551a4d42020-12-08 18:09:20 +00002866 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002867 loCookie := apFlowItem.GetCookie()
2868 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002869 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002870 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302871
dbainbri4d3a0dc2020-12-02 00:33:42 +00002872 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002873 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302874 if loIPProto == 2 {
2875 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2876 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002877 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2878 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302879 return nil
2880 }
mpagenko01e726e2020-10-23 09:45:29 +00002881 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002882 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002883
2884 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002885 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002886 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2887 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2888 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2889 //TODO!!: Use DeviceId within the error response to rwCore
2890 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002891 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002892 }
2893 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002895 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2896 } else {
2897 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2898 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2899 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302900 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002901 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002902 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002903 }
mpagenko9a304ea2020-12-16 15:54:01 +00002904
2905 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002906 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002907 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302908 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002909 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002910 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002911 dh.lockVlanConfig.RUnlock()
2912 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002913 }
mpagenkof1fc3862021-02-16 10:09:52 +00002914 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002916 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002917}
2918
2919//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002921 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2922 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2923 //no extra check is done on the rule parameters
2924 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2925 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2926 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2927 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002928 // - 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 +00002929 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002930 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002931
2932 /* TT related temporary workaround - should not be needed anymore
2933 for _, field := range flow.GetOfbFields(apFlowItem) {
2934 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2935 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002936 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002937 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2938 if loIPProto == 2 {
2939 // 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 +00002940 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002941 log.Fields{"device-id": dh.deviceID})
2942 return nil
2943 }
2944 }
2945 } //for all OfbFields
2946 */
2947
mpagenko9a304ea2020-12-16 15:54:01 +00002948 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002949 dh.lockVlanConfig.RLock()
2950 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002951 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002952 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002953 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002954 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002955 log.Fields{"device-id": dh.deviceID})
2956 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002957 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002959
mpagenko01e726e2020-10-23 09:45:29 +00002960 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002961}
2962
Himani Chawla26e555c2020-08-31 12:30:20 +05302963// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002964// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002965func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002966 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002967 chVlanFilterFsm := make(chan Message, 2048)
2968
dbainbri4d3a0dc2020-12-02 00:33:42 +00002969 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002970 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002971 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302972 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002973 }
2974
dbainbri4d3a0dc2020-12-02 00:33:42 +00002975 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002976 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002977 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002978 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002979 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002980 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2981 // (from parallel processing)
2982 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302983 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002984 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2985 if pVlanFilterStatemachine != nil {
2986 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2987 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302989 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002990 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302991 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002992 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302993 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2994 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002995 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002996 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002997 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302998 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002999 }
3000 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003001 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003002 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303003 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003004 }
3005 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003006 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003007 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303008 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003009 }
3010 return nil
3011}
3012
mpagenkofc4f56e2020-11-04 17:17:49 +00003013//VerifyVlanConfigRequest checks on existence of a given uniPort
3014// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003015func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003016 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3017 var pCurrentUniPort *onuUniPort
3018 for _, uniPort := range dh.uniEntityMap {
3019 // only if this port is validated for operState transfer
3020 if uniPort.uniID == uint8(aUniID) {
3021 pCurrentUniPort = uniPort
3022 break //found - end search loop
3023 }
3024 }
3025 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003026 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003027 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3028 return
3029 }
mpagenko551a4d42020-12-08 18:09:20 +00003030 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003031}
3032
mpagenkodff5dda2020-08-28 11:52:01 +00003033//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003034func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003035 //TODO!! verify and start pending flow configuration
3036 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3037 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003038
3039 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303040 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003041 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003042 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3043 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3044 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003045 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3046 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3047 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3048 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3049 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3050 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3051 } else {
3052 /***** UniVlanConfigFsm continued */
3053 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3054 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3055 "UniPort": apUniPort.portNo})
3056 }
3057 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3058 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3059 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3060 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3061 } else {
3062 /***** UniVlanConfigFsm continued */
3063 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3064 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3065 "UniPort": apUniPort.portNo})
3066 }
mpagenkodff5dda2020-08-28 11:52:01 +00003067 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003068 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3069 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003070 "UniPort": apUniPort.portNo})
3071 }
3072 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003073 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3074 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3075 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003076 }
3077 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003078 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003079 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003080 }
mpagenkof1fc3862021-02-16 10:09:52 +00003081 } else {
3082 dh.lockVlanConfig.RUnlock()
3083 }
mpagenkodff5dda2020-08-28 11:52:01 +00003084}
3085
3086//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3087// 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 +00003088func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3089 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003090 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3091 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003092 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303093 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003094 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003095}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003096
mpagenkof1fc3862021-02-16 10:09:52 +00003097//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3098func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3099 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3100 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3101 // obviously then parallel processing on the cancel must be avoided
3102 // deadline context to ensure completion of background routines waited for
3103 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3104 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3105 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3106
3107 aPDevEntry.resetKvProcessingErrorIndication()
3108 var wg sync.WaitGroup
3109 wg.Add(1) // for the 1 go routine to finish
3110
3111 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3112 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3113
3114 return aPDevEntry.getKvProcessingErrorIndication()
3115}
3116
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003117//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3118//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003119func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3120 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003121
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003122 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003124 return nil
3125 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003126 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003127
dbainbri4d3a0dc2020-12-02 00:33:42 +00003128 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003129 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003130 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003131 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3132 }
3133 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3134
mpagenkof1fc3862021-02-16 10:09:52 +00003135 if aWriteToKvStore {
3136 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3137 }
3138 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003139}
3140
dbainbri4d3a0dc2020-12-02 00:33:42 +00003141func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003142 defer cancel() //ensure termination of context (may be pro forma)
3143 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003144 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003145 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003146}
3147
dbainbri4d3a0dc2020-12-02 00:33:42 +00003148func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003149
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003150 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003151 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003152 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003153 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3154 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003155 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003156 return err
3157 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003158 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003159 return nil
3160 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003161 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003162 return nil
3163}
3164
dbainbri4d3a0dc2020-12-02 00:33:42 +00003165func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3166 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003167 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003168 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003169 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3170 }
mpagenkof1fc3862021-02-16 10:09:52 +00003171 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003172}
3173
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003174func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3175 var errStr string = ""
3176 for _, err := range errS {
3177 if err != nil {
3178 errStr = errStr + err.Error() + " "
3179 }
3180 }
3181 if errStr != "" {
3182 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3183 }
3184 return nil
3185}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003186
3187// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
3188func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3189 dh.lockDevice.RLock()
3190 defer dh.lockDevice.RUnlock()
3191 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3192 return uniPort.entityID, nil
3193 }
3194 return 0, errors.New("error-fetching-uni-port")
3195}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003196
3197// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003198func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3199 var errorsList []error
3200 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 -08003201
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003202 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3203 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3204 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3205
3206 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3207 // successfully.
3208 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3209 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3210 if len(errorsList) > 0 {
3211 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3212 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003213 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003214 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3215 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003216}
3217
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003218func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3219 var err error
3220 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003221 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003222
3223 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3224 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3225 errorsList = append(errorsList, err)
3226 }
3227 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003228 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003229
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003230 return errorsList
3231}
3232
3233func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3234 var err error
3235 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003236 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003237 // Check if group metric related config is updated
3238 for _, v := range pmConfigs.Groups {
3239 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3240 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3241 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3242
3243 if ok && m.frequency != v.GroupFreq {
3244 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3245 errorsList = append(errorsList, err)
3246 }
3247 }
3248 if ok && m.enabled != v.Enabled {
3249 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3250 errorsList = append(errorsList, err)
3251 }
3252 }
3253 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003254 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003255 return errorsList
3256}
3257
3258func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3259 var err error
3260 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003261 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003262 // Check if standalone metric related config is updated
3263 for _, v := range pmConfigs.Metrics {
3264 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003265 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003266 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3267
3268 if ok && m.frequency != v.SampleFreq {
3269 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3270 errorsList = append(errorsList, err)
3271 }
3272 }
3273 if ok && m.enabled != v.Enabled {
3274 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3275 errorsList = append(errorsList, err)
3276 }
3277 }
3278 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003279 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003280 return errorsList
3281}
3282
3283// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003284func (dh *deviceHandler) startCollector(ctx context.Context) {
3285 logger.Debugf(ctx, "startingCollector")
3286
3287 // Start routine to process OMCI GET Responses
3288 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003289 // Initialize the next metric collection time.
3290 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3291 // reset like onu rebooted.
3292 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003293 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003294 for {
3295 select {
3296 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003297 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003298 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003299 // Stop the L2 PM FSM
3300 go func() {
3301 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3302 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3303 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3304 }
3305 } else {
3306 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3307 }
3308 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003309 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3310 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3311 }
3312 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3313 dh.pOnuMetricsMgr.stopTicks <- true
3314 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003315
Girish Gowdrae09a6202021-01-12 18:10:59 -08003316 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003317 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3318 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3319 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3320 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3321 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003322 // Update the next metric collection time.
3323 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003324 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003325 } else {
3326 if dh.pmConfigs.Grouped { // metrics are managed as a group
3327 // parse through the group and standalone metrics to see it is time to collect their metrics
3328 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003329
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003330 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3331 // 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 -08003332 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3333 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003334 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3335 }
3336 }
3337 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3338 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3339 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3340 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3341 }
3342 }
3343 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3344
3345 // parse through the group and update the next metric collection time
3346 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3347 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3348 // 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 -08003349 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3350 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003351 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3352 }
3353 }
3354 // parse through the standalone metrics and update the next metric collection time
3355 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3356 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3357 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3358 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3359 }
3360 }
3361 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3362 } /* else { // metrics are not managed as a group
3363 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3364 } */
3365 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003366 }
3367 }
3368}
kesavandfdf77632021-01-26 23:40:33 -05003369
3370func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3371
3372 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3373 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3374}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003375
mpagenkof1fc3862021-02-16 10:09:52 +00003376func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3377 if pFsm == nil {
3378 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003379 }
mpagenkof1fc3862021-02-16 10:09:52 +00003380 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003381}
3382
mpagenkof1fc3862021-02-16 10:09:52 +00003383func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3384 var pFsm *fsm.FSM
3385 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3386 switch omciFsm {
3387 case cUploadFsm:
3388 {
3389 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3390 }
3391 case cDownloadFsm:
3392 {
3393 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3394 }
3395 case cUniLockFsm:
3396 {
3397 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3398 }
3399 case cUniUnLockFsm:
3400 {
3401 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3402 }
3403 case cL2PmFsm:
3404 {
3405 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3406 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3407 } else {
3408 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003409 }
3410 }
mpagenko80622a52021-02-09 16:53:23 +00003411 case cOnuUpgradeFsm:
3412 {
3413 dh.lockUpgradeFsm.RLock()
3414 defer dh.lockUpgradeFsm.RUnlock()
3415 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3416 }
mpagenkof1fc3862021-02-16 10:09:52 +00003417 default:
3418 {
3419 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3420 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3421 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003422 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003423 }
mpagenkof1fc3862021-02-16 10:09:52 +00003424 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003425}
3426
mpagenkof1fc3862021-02-16 10:09:52 +00003427func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3428 for _, v := range dh.pOnuTP.pAniConfigFsm {
3429 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003430 return false
3431 }
3432 }
3433 return true
3434}
3435
mpagenkof1fc3862021-02-16 10:09:52 +00003436func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3437 dh.lockVlanConfig.RLock()
3438 defer dh.lockVlanConfig.RUnlock()
3439 for _, v := range dh.UniVlanConfigFsmMap {
3440 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3441 return false
3442 }
3443 }
3444 return true //FSM not active - so there is no activity on omci
3445}
3446
3447func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3448 dh.lockVlanConfig.RLock()
3449 defer dh.lockVlanConfig.RUnlock()
3450 for _, v := range dh.UniVlanConfigFsmMap {
3451 if v.pAdaptFsm.pFsm != nil {
3452 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3453 return true //there is at least one VLAN FSM with some active configuration
3454 }
3455 }
3456 }
3457 return false //there is no VLAN FSM with some active configuration
3458}
3459
3460func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3461 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3462 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3463 return false
3464 }
3465 }
3466 // a further check is done to identify, if at least some data traffic related configuration exists
3467 // 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])
3468 return dh.checkUserServiceExists(ctx)
3469}
3470
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003471func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3472 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3473 if err := dh.resetFsms(ctx, false); err != nil {
3474 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3475 // TODO: fatal error reset ONU, delete deviceHandler!
3476 return
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}