blob: 929964c7849cb67e6aca7dd3861fc0cebde0a05d [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
Himani Chawla6d2ae152020-09-02 13:11:20 +05302441 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (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
Himani Chawla6d2ae152020-09-02 13:11:20 +05302460 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002461 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302462 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002463 if !dh.isReconciling() {
2464 //maybe also use getter functions on uniPort - perhaps later ...
2465 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2466 } else {
2467 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2468 }
2469
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002470 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002471 }
2472}
2473
2474// ONU_Active/Inactive announcement on system KAFKA bus
2475// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002476func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002477 var de voltha.DeviceEvent
2478 eventContext := make(map[string]string)
2479 //Populating event context
2480 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002482 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302484 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002485 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 +00002486 }
2487 oltSerialNumber := parentDevice.SerialNumber
2488
2489 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2490 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2491 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302492 eventContext["olt-serial-number"] = oltSerialNumber
2493 eventContext["device-id"] = aDeviceID
2494 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002495 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2496 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2497 deviceEntry.mutexPersOnuConfig.RLock()
2498 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2499 deviceEntry.mutexPersOnuConfig.RUnlock()
2500 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2501 deviceEntry.mutexPersOnuConfig.RLock()
2502 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2503 deviceEntry.mutexPersOnuConfig.RUnlock()
2504 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2505 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2506 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2507 } else {
2508 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2509 log.Fields{"device-id": aDeviceID})
2510 return
2511 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002512
2513 /* Populating device event body */
2514 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302515 de.ResourceId = aDeviceID
2516 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002517 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2518 de.Description = fmt.Sprintf("%s Event - %s - %s",
2519 cEventObjectType, cOnuActivatedEvent, "Raised")
2520 } else {
2521 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2522 de.Description = fmt.Sprintf("%s Event - %s - %s",
2523 cEventObjectType, cOnuActivatedEvent, "Cleared")
2524 }
2525 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2527 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302528 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002529 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002530 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302531 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002532}
2533
Himani Chawla4d908332020-08-31 12:30:20 +05302534// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002535func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002536 chLSFsm := make(chan Message, 2048)
2537 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302538 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002540 sFsmName = "LockStateFSM"
2541 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002543 sFsmName = "UnLockStateFSM"
2544 }
mpagenko3af1f032020-06-10 08:53:41 +00002545
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002547 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002548 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002549 return
2550 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002551 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002552 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002553 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302554 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002555 dh.pLockStateFsm = pLSFsm
2556 } else {
2557 dh.pUnlockStateFsm = pLSFsm
2558 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002560 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002561 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002562 }
2563}
2564
2565// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002567 /* Uni Port lock/unlock procedure -
2568 ***** should run via 'adminDone' state and generate the argument requested event *****
2569 */
2570 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302571 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002572 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2573 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2574 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002575 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302576 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002577 }
2578 } else {
2579 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2580 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2581 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002582 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302583 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002584 }
2585 }
2586 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002587 if pLSStatemachine.Is(uniStDisabled) {
2588 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002589 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002590 // maybe try a FSM reset and then again ... - TODO!!!
2591 } else {
2592 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002593 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002594 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002595 }
2596 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002597 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002598 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002599 // maybe try a FSM reset and then again ... - TODO!!!
2600 }
2601 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002602 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002603 // maybe try a FSM reset and then again ... - TODO!!!
2604 }
2605}
2606
mpagenko80622a52021-02-09 16:53:23 +00002607// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002608func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002609 //in here lockUpgradeFsm is already locked
2610 chUpgradeFsm := make(chan Message, 2048)
2611 var sFsmName = "OnuSwUpgradeFSM"
2612 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002613 if apDevEntry.PDevOmciCC == nil {
2614 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2615 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002616 }
mpagenko15ff4a52021-03-02 10:09:20 +00002617 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002618 sFsmName, chUpgradeFsm)
2619 if dh.pOnuUpradeFsm != nil {
2620 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2621 if pUpgradeStatemachine != nil {
2622 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002623 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002624 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2625 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2626 // maybe try a FSM reset and then again ... - TODO!!!
2627 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2628 }
2629 /***** LockStateFSM started */
2630 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2631 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2632 } else {
2633 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2634 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2635 // maybe try a FSM reset and then again ... - TODO!!!
2636 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2637 }
2638 } else {
2639 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2640 // maybe try a FSM reset and then again ... - TODO!!!
2641 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2642 }
2643 } else {
2644 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2645 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2646 }
2647 return nil
2648}
2649
2650// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2651func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2652 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2653 "device-id": dh.deviceID})
2654 dh.lockUpgradeFsm.Lock()
2655 defer dh.lockUpgradeFsm.Unlock()
2656 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2657}
2658
mpagenko15ff4a52021-03-02 10:09:20 +00002659// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2660func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2661 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2662 if pDevEntry == nil {
2663 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2664 return
2665 }
2666
2667 dh.lockUpgradeFsm.RLock()
2668 defer dh.lockUpgradeFsm.RUnlock()
2669 if dh.pOnuUpradeFsm != nil {
2670 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2671 if pUpgradeStatemachine != nil {
2672 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2673 // (some manual forced commit could do without)
2674 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko183647c2021-06-08 15:25:04 +00002675 // 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 +00002676 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002677 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2678 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2679 return
2680 }
2681 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2682 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2683 } else {
2684 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2685 log.Fields{"device-id": dh.deviceID})
2686 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2687 return
2688 }
mpagenko183647c2021-06-08 15:25:04 +00002689 } else {
2690 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2691 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2692 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2693 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2694 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2695 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2696 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2697 }
2698 }
mpagenko15ff4a52021-03-02 10:09:20 +00002699 }
2700 }
2701 } else {
2702 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2703 }
2704}
2705
Himani Chawla6d2ae152020-09-02 13:11:20 +05302706//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002707func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002708
2709 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002710 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002711 kvbackend := &db.Backend{
2712 Client: dh.pOpenOnuAc.kvClient,
2713 StoreType: dh.pOpenOnuAc.KVStoreType,
2714 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002715 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002716 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2717 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002718
mpagenkoaf801632020-07-03 10:00:42 +00002719 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002720}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302722 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002723
mpagenkodff5dda2020-08-28 11:52:01 +00002724 for _, field := range flow.GetOfbFields(apFlowItem) {
2725 switch field.Type {
2726 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2727 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002728 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002729 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2730 }
mpagenko01e726e2020-10-23 09:45:29 +00002731 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002732 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2733 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302734 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002735 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302736 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2737 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002738 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2739 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002740 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2741 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302742 return
mpagenkodff5dda2020-08-28 11:52:01 +00002743 }
2744 }
mpagenko01e726e2020-10-23 09:45:29 +00002745 */
mpagenkodff5dda2020-08-28 11:52:01 +00002746 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2747 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302748 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002749 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302750 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002751 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302752 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002753 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302755 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002756 }
2757 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2758 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302759 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002760 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002761 "PCP": loAddPcp})
2762 }
2763 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2764 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002765 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002766 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2767 }
2768 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2769 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002770 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002771 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2772 }
2773 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2774 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002775 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002776 "IPv4-DST": field.GetIpv4Dst()})
2777 }
2778 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2779 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002780 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002781 "IPv4-SRC": field.GetIpv4Src()})
2782 }
2783 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2784 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002785 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002786 "Metadata": field.GetTableMetadata()})
2787 }
2788 /*
2789 default:
2790 {
2791 //all other entires ignored
2792 }
2793 */
2794 }
2795 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302796}
mpagenkodff5dda2020-08-28 11:52:01 +00002797
dbainbri4d3a0dc2020-12-02 00:33:42 +00002798func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002799 for _, action := range flow.GetActions(apFlowItem) {
2800 switch action.Type {
2801 /* not used:
2802 case of.OfpActionType_OFPAT_OUTPUT:
2803 {
mpagenko01e726e2020-10-23 09:45:29 +00002804 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002805 "Output": action.GetOutput()})
2806 }
2807 */
2808 case of.OfpActionType_OFPAT_PUSH_VLAN:
2809 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002810 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002811 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2812 }
2813 case of.OfpActionType_OFPAT_SET_FIELD:
2814 {
2815 pActionSetField := action.GetSetField()
2816 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002817 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002818 "OxcmClass": pActionSetField.Field.OxmClass})
2819 }
2820 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302821 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302823 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002824 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302825 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002826 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302827 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002828 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002829 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002830 "Type": pActionSetField.Field.GetOfbField().Type})
2831 }
2832 }
2833 /*
2834 default:
2835 {
2836 //all other entires ignored
2837 }
2838 */
2839 }
2840 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302841}
2842
2843//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002844func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302845 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2846 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2847 var loAddPcp, loSetPcp uint8
2848 var loIPProto uint32
2849 /* the TechProfileId is part of the flow Metadata - compare also comment within
2850 * OLT-Adapter:openolt_flowmgr.go
2851 * Metadata 8 bytes:
2852 * Most Significant 2 Bytes = Inner VLAN
2853 * Next 2 Bytes = Tech Profile ID(TPID)
2854 * Least Significant 4 Bytes = Port ID
2855 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2856 * subscriber related flows.
2857 */
2858
dbainbri4d3a0dc2020-12-02 00:33:42 +00002859 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302860 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002861 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302862 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002863 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302864 }
mpagenko551a4d42020-12-08 18:09:20 +00002865 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002866 loCookie := apFlowItem.GetCookie()
2867 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002868 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002869 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302870
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002872 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302873 if loIPProto == 2 {
2874 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2875 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002876 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2877 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302878 return nil
2879 }
mpagenko01e726e2020-10-23 09:45:29 +00002880 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002881 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002882
2883 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002885 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2886 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2887 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2888 //TODO!!: Use DeviceId within the error response to rwCore
2889 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002890 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002891 }
2892 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002894 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2895 } else {
2896 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2897 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2898 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302899 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002900 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002901 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002902 }
mpagenko9a304ea2020-12-16 15:54:01 +00002903
2904 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002905 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002906 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302907 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002908 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002909 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002910 dh.lockVlanConfig.RUnlock()
2911 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002912 }
mpagenkof1fc3862021-02-16 10:09:52 +00002913 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002914 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002915 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002916}
2917
2918//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002919func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002920 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2921 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2922 //no extra check is done on the rule parameters
2923 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2924 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2925 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2926 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002927 // - 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 +00002928 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002929 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002930
2931 /* TT related temporary workaround - should not be needed anymore
2932 for _, field := range flow.GetOfbFields(apFlowItem) {
2933 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2934 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002935 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002936 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2937 if loIPProto == 2 {
2938 // 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 +00002939 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002940 log.Fields{"device-id": dh.deviceID})
2941 return nil
2942 }
2943 }
2944 } //for all OfbFields
2945 */
2946
mpagenko9a304ea2020-12-16 15:54:01 +00002947 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002948 dh.lockVlanConfig.RLock()
2949 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002950 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002951 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002952 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002953 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002954 log.Fields{"device-id": dh.deviceID})
2955 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002956 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002957 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002958
mpagenko01e726e2020-10-23 09:45:29 +00002959 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002960}
2961
Himani Chawla26e555c2020-08-31 12:30:20 +05302962// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002963// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002964func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002965 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002966 chVlanFilterFsm := make(chan Message, 2048)
2967
dbainbri4d3a0dc2020-12-02 00:33:42 +00002968 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002969 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002970 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302971 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002972 }
2973
dbainbri4d3a0dc2020-12-02 00:33:42 +00002974 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002975 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002976 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00002977 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002978 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002979 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2980 // (from parallel processing)
2981 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302982 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002983 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2984 if pVlanFilterStatemachine != nil {
2985 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2986 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002987 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302988 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002989 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302990 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002991 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302992 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2993 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002994 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002995 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002996 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302997 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002998 }
2999 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003000 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003001 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303002 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003003 }
3004 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003005 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003006 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303007 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003008 }
3009 return nil
3010}
3011
mpagenkofc4f56e2020-11-04 17:17:49 +00003012//VerifyVlanConfigRequest checks on existence of a given uniPort
3013// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003014func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003015 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3016 var pCurrentUniPort *onuUniPort
3017 for _, uniPort := range dh.uniEntityMap {
3018 // only if this port is validated for operState transfer
3019 if uniPort.uniID == uint8(aUniID) {
3020 pCurrentUniPort = uniPort
3021 break //found - end search loop
3022 }
3023 }
3024 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003025 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003026 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3027 return
3028 }
mpagenko551a4d42020-12-08 18:09:20 +00003029 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003030}
3031
mpagenkodff5dda2020-08-28 11:52:01 +00003032//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003033func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003034 //TODO!! verify and start pending flow configuration
3035 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3036 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003037
3038 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303039 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003040 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003041 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3042 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3043 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003044 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3045 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3046 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3047 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3048 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3049 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3050 } else {
3051 /***** UniVlanConfigFsm continued */
3052 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3053 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3054 "UniPort": apUniPort.portNo})
3055 }
3056 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3057 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3058 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3059 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3060 } else {
3061 /***** UniVlanConfigFsm continued */
3062 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3063 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3064 "UniPort": apUniPort.portNo})
3065 }
mpagenkodff5dda2020-08-28 11:52:01 +00003066 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003067 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3068 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003069 "UniPort": apUniPort.portNo})
3070 }
3071 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003072 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3073 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3074 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003075 }
3076 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003077 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003078 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003079 }
mpagenkof1fc3862021-02-16 10:09:52 +00003080 } else {
3081 dh.lockVlanConfig.RUnlock()
3082 }
mpagenkodff5dda2020-08-28 11:52:01 +00003083}
3084
3085//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3086// 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 +00003087func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3088 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003089 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3090 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003091 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303092 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003093 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003094}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003095
mpagenkof1fc3862021-02-16 10:09:52 +00003096//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3097func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3098 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3099 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3100 // obviously then parallel processing on the cancel must be avoided
3101 // deadline context to ensure completion of background routines waited for
3102 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3103 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3104 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3105
3106 aPDevEntry.resetKvProcessingErrorIndication()
3107 var wg sync.WaitGroup
3108 wg.Add(1) // for the 1 go routine to finish
3109
3110 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3111 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3112
3113 return aPDevEntry.getKvProcessingErrorIndication()
3114}
3115
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003116//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3117//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003118func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3119 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003120
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003121 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003122 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003123 return nil
3124 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003125 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003126
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003128 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003129 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003130 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3131 }
3132 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3133
mpagenkof1fc3862021-02-16 10:09:52 +00003134 if aWriteToKvStore {
3135 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3136 }
3137 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003138}
3139
dbainbri4d3a0dc2020-12-02 00:33:42 +00003140func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003141 defer cancel() //ensure termination of context (may be pro forma)
3142 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003143 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003144 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003145}
3146
dbainbri4d3a0dc2020-12-02 00:33:42 +00003147func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003148
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003149 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003150 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003151 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003152 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3153 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003154 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003155 return err
3156 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003157 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003158 return nil
3159 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003160 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003161 return nil
3162}
3163
dbainbri4d3a0dc2020-12-02 00:33:42 +00003164func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3165 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003166 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003167 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003168 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3169 }
mpagenkof1fc3862021-02-16 10:09:52 +00003170 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003171}
3172
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003173func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3174 var errStr string = ""
3175 for _, err := range errS {
3176 if err != nil {
3177 errStr = errStr + err.Error() + " "
3178 }
3179 }
3180 if errStr != "" {
3181 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3182 }
3183 return nil
3184}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003185
3186// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
3187func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3188 dh.lockDevice.RLock()
3189 defer dh.lockDevice.RUnlock()
3190 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3191 return uniPort.entityID, nil
3192 }
3193 return 0, errors.New("error-fetching-uni-port")
3194}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003195
3196// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003197func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3198 var errorsList []error
3199 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 -08003200
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003201 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3202 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3203 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3204
3205 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3206 // successfully.
3207 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3208 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3209 if len(errorsList) > 0 {
3210 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3211 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003212 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003213 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3214 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003215}
3216
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003217func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3218 var err error
3219 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003220 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003221
3222 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3223 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3224 errorsList = append(errorsList, err)
3225 }
3226 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003227 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003228
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003229 return errorsList
3230}
3231
3232func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3233 var err error
3234 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003235 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003236 // Check if group metric related config is updated
3237 for _, v := range pmConfigs.Groups {
3238 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3239 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3240 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3241
3242 if ok && m.frequency != v.GroupFreq {
3243 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3244 errorsList = append(errorsList, err)
3245 }
3246 }
3247 if ok && m.enabled != v.Enabled {
3248 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3249 errorsList = append(errorsList, err)
3250 }
3251 }
3252 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003253 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003254 return errorsList
3255}
3256
3257func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3258 var err error
3259 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003260 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003261 // Check if standalone metric related config is updated
3262 for _, v := range pmConfigs.Metrics {
3263 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003264 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003265 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3266
3267 if ok && m.frequency != v.SampleFreq {
3268 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3269 errorsList = append(errorsList, err)
3270 }
3271 }
3272 if ok && m.enabled != v.Enabled {
3273 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3274 errorsList = append(errorsList, err)
3275 }
3276 }
3277 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003278 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003279 return errorsList
3280}
3281
3282// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003283func (dh *deviceHandler) startCollector(ctx context.Context) {
3284 logger.Debugf(ctx, "startingCollector")
3285
3286 // Start routine to process OMCI GET Responses
3287 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003288 // Initialize the next metric collection time.
3289 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3290 // reset like onu rebooted.
3291 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003292 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003293 for {
3294 select {
3295 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003296 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003297 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003298 // Stop the L2 PM FSM
3299 go func() {
3300 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3301 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3302 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3303 }
3304 } else {
3305 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3306 }
3307 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003308 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3309 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3310 }
3311 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3312 dh.pOnuMetricsMgr.stopTicks <- true
3313 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003314
Girish Gowdrae09a6202021-01-12 18:10:59 -08003315 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003316 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3317 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3318 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3319 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3320 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003321 // Update the next metric collection time.
3322 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003323 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003324 } else {
3325 if dh.pmConfigs.Grouped { // metrics are managed as a group
3326 // parse through the group and standalone metrics to see it is time to collect their metrics
3327 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003328
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003329 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3330 // 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 -08003331 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3332 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003333 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3334 }
3335 }
3336 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3337 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3338 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3339 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3340 }
3341 }
3342 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3343
3344 // parse through the group and update the next metric collection time
3345 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3346 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3347 // 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 -08003348 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3349 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003350 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3351 }
3352 }
3353 // parse through the standalone metrics and update the next metric collection time
3354 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3355 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3356 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3357 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3358 }
3359 }
3360 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3361 } /* else { // metrics are not managed as a group
3362 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3363 } */
3364 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003365 }
3366 }
3367}
kesavandfdf77632021-01-26 23:40:33 -05003368
3369func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3370
3371 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3372 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3373}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003374
mpagenkof1fc3862021-02-16 10:09:52 +00003375func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3376 if pFsm == nil {
3377 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003378 }
mpagenkof1fc3862021-02-16 10:09:52 +00003379 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003380}
3381
mpagenkof1fc3862021-02-16 10:09:52 +00003382func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3383 var pFsm *fsm.FSM
3384 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3385 switch omciFsm {
3386 case cUploadFsm:
3387 {
3388 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3389 }
3390 case cDownloadFsm:
3391 {
3392 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3393 }
3394 case cUniLockFsm:
3395 {
3396 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3397 }
3398 case cUniUnLockFsm:
3399 {
3400 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3401 }
3402 case cL2PmFsm:
3403 {
3404 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3405 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3406 } else {
3407 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003408 }
3409 }
mpagenko80622a52021-02-09 16:53:23 +00003410 case cOnuUpgradeFsm:
3411 {
3412 dh.lockUpgradeFsm.RLock()
3413 defer dh.lockUpgradeFsm.RUnlock()
3414 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3415 }
mpagenkof1fc3862021-02-16 10:09:52 +00003416 default:
3417 {
3418 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3419 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3420 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003421 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003422 }
mpagenkof1fc3862021-02-16 10:09:52 +00003423 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003424}
3425
mpagenkof1fc3862021-02-16 10:09:52 +00003426func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3427 for _, v := range dh.pOnuTP.pAniConfigFsm {
3428 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003429 return false
3430 }
3431 }
3432 return true
3433}
3434
mpagenkof1fc3862021-02-16 10:09:52 +00003435func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3436 dh.lockVlanConfig.RLock()
3437 defer dh.lockVlanConfig.RUnlock()
3438 for _, v := range dh.UniVlanConfigFsmMap {
3439 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3440 return false
3441 }
3442 }
3443 return true //FSM not active - so there is no activity on omci
3444}
3445
3446func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3447 dh.lockVlanConfig.RLock()
3448 defer dh.lockVlanConfig.RUnlock()
3449 for _, v := range dh.UniVlanConfigFsmMap {
3450 if v.pAdaptFsm.pFsm != nil {
3451 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3452 return true //there is at least one VLAN FSM with some active configuration
3453 }
3454 }
3455 }
3456 return false //there is no VLAN FSM with some active configuration
3457}
3458
3459func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3460 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3461 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3462 return false
3463 }
3464 }
3465 // a further check is done to identify, if at least some data traffic related configuration exists
3466 // 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])
3467 return dh.checkUserServiceExists(ctx)
3468}
3469
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003470func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3471 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3472 if err := dh.resetFsms(ctx, false); err != nil {
3473 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3474 // TODO: fatal error reset ONU, delete deviceHandler!
3475 return
3476 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003477 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003478 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003479}
3480
3481func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3482 dh.mutexCollectorFlag.Lock()
3483 dh.collectorIsRunning = flagValue
3484 dh.mutexCollectorFlag.Unlock()
3485}
3486
3487func (dh *deviceHandler) getCollectorIsRunning() bool {
3488 dh.mutexCollectorFlag.RLock()
3489 flagValue := dh.collectorIsRunning
3490 dh.mutexCollectorFlag.RUnlock()
3491 return flagValue
3492}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303493
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303494func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3495 dh.mutextAlarmManagerFlag.Lock()
3496 dh.alarmManagerIsRunning = flagValue
3497 dh.mutextAlarmManagerFlag.Unlock()
3498}
3499
Himani Chawla1472c682021-03-17 17:11:14 +05303500func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303501 dh.mutextAlarmManagerFlag.RLock()
3502 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303503 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303504 dh.mutextAlarmManagerFlag.RUnlock()
3505 return flagValue
3506}
3507
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303508func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3509 logger.Debugf(ctx, "startingAlarmManager")
3510
3511 // Start routine to process OMCI GET Responses
3512 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303513 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303514 if stop := <-dh.stopAlarmManager; stop {
3515 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303516 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303517 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303518 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3519 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3520 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303521 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303522 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303523 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3524 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303525 }
3526}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003527
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003528func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003529 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003530
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003531 if !dh.isReconciling() {
3532 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003533 logger.Debugw(ctx, "wait for channel signal or timeout",
3534 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003535 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003536 case success := <-dh.chReconcilingFinished:
3537 if success {
Maninderb5187552021-03-23 22:23:42 +05303538 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3539 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3540 log.Fields{"device-id": dh.deviceID})
3541 } else {
3542 connectStatus := voltha.ConnectStatus_UNREACHABLE
3543 operState := voltha.OperStatus_UNKNOWN
3544 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3545 connectStatus = voltha.ConnectStatus_REACHABLE
3546 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3547 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3548 operState = voltha.OperStatus_ACTIVE
3549 } else {
3550 operState = voltha.OperStatus_ACTIVATING
3551 }
3552 }
3553 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3554 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3555 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3556 operState = voltha.OperStatus_DISCOVERED
3557 }
3558
3559 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
3560 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3561 logger.Errorw(ctx, "unable to update device state to core",
3562 log.Fields{"OperState": onuDevEntry.sOnuPersistentData.PersOperState, "Err": err})
3563 }
3564 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003565 logger.Debugw(ctx, "reconciling has been finished in time",
3566 log.Fields{"device-id": dh.deviceID})
3567 } else {
Maninderb5187552021-03-23 22:23:42 +05303568 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003569 log.Fields{"device-id": dh.deviceID})
3570 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003571 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Maninderb5187552021-03-23 22:23:42 +05303572 //TODO: handle notification to core if reconciling timed out
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003573 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3574 log.Fields{"device-id": dh.deviceID})
3575 }
3576 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003577 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003578 dh.mutexReconcilingFlag.Unlock()
3579 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003580 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003581 dh.mutexReconcilingFlag.Lock()
3582 if skipOnuConfig {
3583 dh.reconciling = cSkipOnuConfigReconciling
3584 } else {
3585 dh.reconciling = cOnuConfigReconciling
3586 }
3587 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003588}
3589
3590func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3591 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3592 if dh.isReconciling() {
3593 dh.chReconcilingFinished <- true
3594 } else {
3595 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3596 }
3597}
3598
3599func (dh *deviceHandler) isReconciling() bool {
3600 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003601 defer dh.mutexReconcilingFlag.RUnlock()
3602 return dh.reconciling != cNoReconciling
3603}
3604
3605func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3606 dh.mutexReconcilingFlag.RLock()
3607 defer dh.mutexReconcilingFlag.RUnlock()
3608 return dh.reconciling == cSkipOnuConfigReconciling
3609}
3610
3611func (dh *deviceHandler) setDeviceReason(value uint8) {
3612 dh.mutexDeviceReason.Lock()
3613 dh.deviceReason = value
3614 dh.mutexDeviceReason.Unlock()
3615}
3616
3617func (dh *deviceHandler) getDeviceReason() uint8 {
3618 dh.mutexDeviceReason.RLock()
3619 value := dh.deviceReason
3620 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003621 return value
3622}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003623
3624func (dh *deviceHandler) getDeviceReasonString() string {
3625 return deviceReasonMap[dh.getDeviceReason()]
3626}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003627
3628func (dh *deviceHandler) setReconcilingFlows(value bool) {
3629 dh.mutexReconcilingFlowsFlag.Lock()
3630 dh.reconcilingFlows = value
3631 dh.mutexReconcilingFlowsFlag.Unlock()
3632}
3633
3634func (dh *deviceHandler) isReconcilingFlows() bool {
3635 dh.mutexReconcilingFlowsFlag.RLock()
3636 value := dh.reconcilingFlows
3637 dh.mutexReconcilingFlowsFlag.RUnlock()
3638 return value
3639}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003640
3641func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3642 dh.mutexReadyForOmciConfig.Lock()
3643 dh.readyForOmciConfig = flagValue
3644 dh.mutexReadyForOmciConfig.Unlock()
3645}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003646func (dh *deviceHandler) isReadyForOmciConfig() bool {
3647 dh.mutexReadyForOmciConfig.RLock()
3648 flagValue := dh.readyForOmciConfig
3649 dh.mutexReadyForOmciConfig.RUnlock()
3650 return flagValue
3651}