blob: 2d4d67dd24b430375b42252908b5f78e96b6df6f [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
188 exitChannel chan int
189 lockDevice sync.RWMutex
190 pOnuIndication *oop.OnuIndication
191 deviceReason uint8
192 mutexDeviceReason sync.RWMutex
193 pLockStateFsm *lockStateFsm
194 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000195
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196 //flowMgr *OpenOltFlowMgr
197 //eventMgr *OpenOltEventMgr
198 //resourceMgr *rsrcMgr.OpenOltResourceMgr
199
200 //discOnus sync.Map
201 //onus sync.Map
202 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000203 collectorIsRunning bool
204 mutexCollectorFlag sync.RWMutex
205 stopCollector chan bool
206 alarmManagerIsRunning bool
207 mutextAlarmManagerFlag sync.RWMutex
208 stopAlarmManager chan bool
209 stopHeartbeatCheck chan bool
210 uniEntityMap map[uint32]*onuUniPort
211 mutexKvStoreContext sync.Mutex
212 lockVlanConfig sync.RWMutex
213 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
214 lockUpgradeFsm sync.RWMutex
215 pOnuUpradeFsm *OnuUpgradeFsm
216 reconciling uint8
217 mutexReconcilingFlag sync.RWMutex
218 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000219 reconcilingFlows bool
220 mutexReconcilingFlowsFlag sync.RWMutex
221 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000222 ReadyForSpecificOmciConfig bool
223 deletionInProgress bool
224 mutexDeletionInProgressFlag sync.RWMutex
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225}
226
Himani Chawla6d2ae152020-09-02 13:11:20 +0530227//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530228func 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 +0530229 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230 dh.coreProxy = cp
231 dh.AdapterProxy = ap
232 dh.EventProxy = ep
233 cloned := (proto.Clone(device)).(*voltha.Device)
234 dh.deviceID = cloned.Id
235 dh.DeviceType = cloned.Type
236 dh.adminState = "up"
237 dh.device = cloned
238 dh.pOpenOnuAc = adapter
239 dh.exitChannel = make(chan int, 1)
240 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000241 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000242 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530244 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530245 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 dh.stopHeartbeatCheck = make(chan bool, 2)
247 //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 +0000248 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530249 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000250 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000251 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000252 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000253 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000254 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000255 dh.reconcilingFlows = false
256 dh.chReconcilingFlowsFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000257 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000258 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800260 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
261 dh.pmConfigs = cloned.PmConfigs
262 } /* else {
263 // will be populated when onu_metrics_mananger is initialized.
264 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800265
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000266 // Device related state machine
267 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000268 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000270 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
271 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
272 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
273 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
274 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000275 },
276 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
278 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
279 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
280 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
281 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
282 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
283 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
284 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000285 },
286 )
mpagenkoaf801632020-07-03 10:00:42 +0000287
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 return &dh
289}
290
Himani Chawla6d2ae152020-09-02 13:11:20 +0530291// start save the device to the data model
292func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000293 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000294 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000295 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296}
297
Himani Chawla4d908332020-08-31 12:30:20 +0530298/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530300func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000301 logger.Debug("stopping-device-handler")
302 dh.exitChannel <- 1
303}
Himani Chawla4d908332020-08-31 12:30:20 +0530304*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305
306// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530307// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308
Girish Gowdrae0140f02021-02-02 16:55:09 -0800309//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312
dbainbri4d3a0dc2020-12-02 00:33:42 +0000313 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000314 if dh.pDeviceStateFsm.Is(devStNull) {
315 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000317 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000318 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800319 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
320 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800321 // Now, set the initial PM configuration for that device
322 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
323 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
324 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800325 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 }
329
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330}
331
mpagenko057889c2021-01-21 16:51:58 +0000332func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530333 msgBody := msg.GetBody()
334 omciMsg := &ic.InterAdapterOmciMessage{}
335 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530337 "device-id": dh.deviceID, "error": err})
338 return err
339 }
340
mpagenko80622a52021-02-09 16:53:23 +0000341 /* 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 +0530342 //assuming omci message content is hex coded!
343 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000346 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000349 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000351 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000352 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 +0530353 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000355 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530356}
357
Himani Chawla6d2ae152020-09-02 13:11:20 +0530358func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000361
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000363
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
368 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530369 if dh.pOnuTP == nil {
370 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000373 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000375 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000376 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000377 "device-state": dh.getDeviceReasonString()})
378 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000380 //previous state test here was just this one, now extended for more states to reject the SetRequest:
381 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
382 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530383
384 msgBody := msg.GetBody()
385 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
386 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000387 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 "device-id": dh.deviceID, "error": err})
389 return err
390 }
391
392 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
394 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000397
398 if techProfMsg.UniId > 255 {
399 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
400 techProfMsg.UniId, dh.deviceID))
401 }
402 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800403 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
404 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000405 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800406 return err
407 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408
dbainbri4d3a0dc2020-12-02 00:33:42 +0000409 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 // if there has been some change for some uni TechProfilePath
411 //in order to allow concurrent calls to other dh instances we do not wait for execution here
412 //but doing so we can not indicate problems to the caller (who does what with that then?)
413 //by now we just assume straightforward successful execution
414 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
415 // possible problems to the caller later autonomously
416
417 // deadline context to ensure completion of background routines waited for
418 //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 +0530419 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530420 dctx, cancel := context.WithDeadline(context.Background(), deadline)
421
Girish Gowdra041dcb32020-11-16 16:54:30 -0800422 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 pDevEntry.resetKvProcessingErrorIndication()
424
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 var wg sync.WaitGroup
426 wg.Add(2) // for the 2 go routines to finish
427 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
429 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
430 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000431
Girish Gowdra041dcb32020-11-16 16:54:30 -0800432 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530433 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000434 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 return nil
436}
437
Himani Chawla6d2ae152020-09-02 13:11:20 +0530438func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000439 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 msg *ic.InterAdapterMessage) error {
441
dbainbri4d3a0dc2020-12-02 00:33:42 +0000442 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000443
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000446 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
448 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 if dh.pOnuTP == nil {
450 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530454 }
455
456 msgBody := msg.GetBody()
457 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
458 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530460 "device-id": dh.deviceID, "error": err})
461 return err
462 }
463
464 //compare TECH_PROFILE_DOWNLOAD_REQUEST
465 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530467
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000468 if delGemPortMsg.UniId > 255 {
469 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
470 delGemPortMsg.UniId, dh.deviceID))
471 }
472 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800473 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
474 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000475 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 -0800476 return err
477 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530478
mpagenkofc4f56e2020-11-04 17:17:49 +0000479 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000480
mpagenkofc4f56e2020-11-04 17:17:49 +0000481 // deadline context to ensure completion of background routines waited for
482 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
483 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484
Girish Gowdra041dcb32020-11-16 16:54:30 -0800485 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000486
mpagenkofc4f56e2020-11-04 17:17:49 +0000487 var wg sync.WaitGroup
488 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000490 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000492
Girish Gowdra041dcb32020-11-16 16:54:30 -0800493 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530494}
495
Himani Chawla6d2ae152020-09-02 13:11:20 +0530496func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000497 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530498 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499
dbainbri4d3a0dc2020-12-02 00:33:42 +0000500 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000501
dbainbri4d3a0dc2020-12-02 00:33:42 +0000502 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000504 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000505 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
506 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530507 if dh.pOnuTP == nil {
508 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530510 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530512 }
513
514 msgBody := msg.GetBody()
515 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
516 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000517 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530518 "device-id": dh.deviceID, "error": err})
519 return err
520 }
521
522 //compare TECH_PROFILE_DOWNLOAD_REQUEST
523 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525
526 if delTcontMsg.UniId > 255 {
527 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
528 delTcontMsg.UniId, dh.deviceID))
529 }
530 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800531 tpPath := delTcontMsg.TpPath
532 tpID, err := GetTpIDFromTpPath(tpPath)
533 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800535 return err
536 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530539 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530540 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 dctx, cancel := context.WithDeadline(context.Background(), deadline)
542
Girish Gowdra041dcb32020-11-16 16:54:30 -0800543 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000544 pDevEntry.resetKvProcessingErrorIndication()
545
Himani Chawla26e555c2020-08-31 12:30:20 +0530546 var wg sync.WaitGroup
547 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530549 cResourceTcont, delTcontMsg.AllocId, &wg)
550 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
552 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553
Girish Gowdra041dcb32020-11-16 16:54:30 -0800554 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530555 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530556 return nil
557}
558
Himani Chawla6d2ae152020-09-02 13:11:20 +0530559//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000560// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
561// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000562func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000563 msgID := msg.Header.Id
564 msgType := msg.Header.Type
565 fromTopic := msg.Header.FromTopic
566 toTopic := msg.Header.ToTopic
567 toDeviceID := msg.Header.ToDeviceId
568 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000570 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
571
572 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000573 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000574 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
575 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000576 {
mpagenko057889c2021-01-21 16:51:58 +0000577 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000578 }
mpagenkoaf801632020-07-03 10:00:42 +0000579 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
580 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000582 }
583 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
584 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000585 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000586
mpagenkoaf801632020-07-03 10:00:42 +0000587 }
588 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
589 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000591 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000592 default:
593 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000594 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000595 "msgType": msg.Header.Type, "device-id": dh.deviceID})
596 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000597 }
598 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000599}
600
mpagenkodff5dda2020-08-28 11:52:01 +0000601//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000602func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
603 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000604 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000606
mpagenko01e726e2020-10-23 09:45:29 +0000607 var retError error = nil
608 //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 +0000609 if apOfFlowChanges.ToRemove != nil {
610 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000611 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000613 "device-id": dh.deviceID})
614 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000615 continue
616 }
617 flowInPort := flow.GetInPort(flowItem)
618 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 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 +0000620 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
621 continue
622 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000623 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000624 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000626 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000627 continue
628 } else {
629 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530630 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000631 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
632 loUniPort = uniPort
633 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000635 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
636 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
637 flowInPort, dh.deviceID)
638 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000639 }
640 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000642 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000643 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000645 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000646 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000648 log.Fields{"device-id": dh.deviceID, "error": err})
649 retError = err
650 continue
651 //return err
652 } else { // if last setting succeeds, overwrite possibly previously set error
653 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000654 }
655 }
656 }
657 }
mpagenko01e726e2020-10-23 09:45:29 +0000658 if apOfFlowChanges.ToAdd != nil {
659 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
660 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000661 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000662 "device-id": dh.deviceID})
663 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
664 continue
665 }
666 flowInPort := flow.GetInPort(flowItem)
667 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 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 +0000669 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
670 continue
671 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
672 } else if flowInPort == dh.ponPortNumber {
673 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000675 "device-id": dh.deviceID, "inPort": flowInPort})
676 continue
677 } else {
678 // this is the relevant upstream flow
679 var loUniPort *onuUniPort
680 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
681 loUniPort = uniPort
682 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000684 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
685 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
686 flowInPort, dh.deviceID)
687 continue
688 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
689 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000690 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
691 // if not, we just throw some error here to have an indication about that, if we really need to support that
692 // then we would need to create some means to activate the internal stored flows
693 // after the device gets active automatically (and still with its dependency to the TechProfile)
694 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
695 // also abort for the other still possible flows here
696 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000698 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000699 return fmt.Errorf("improper device state on device %s", dh.deviceID)
700 }
701
mpagenko01e726e2020-10-23 09:45:29 +0000702 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000704 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
705 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000707 //try next flow after processing error
708 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000710 log.Fields{"device-id": dh.deviceID, "error": err})
711 retError = err
712 continue
713 //return err
714 } else { // if last setting succeeds, overwrite possibly previously set error
715 retError = nil
716 }
717 }
718 }
719 }
720 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000721}
722
Himani Chawla6d2ae152020-09-02 13:11:20 +0530723//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000724//following are the expected device states after this activity:
725//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
726// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
728 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000729
mpagenko900ee4b2020-10-12 11:56:34 +0000730 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000731 //note that disableDevice sequences in some 'ONU active' state may yield also
732 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000733 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000734 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000735 //disable-device shall be just a UNi/ONU-G related admin state setting
736 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000737
mpagenkofc4f56e2020-11-04 17:17:49 +0000738 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000739 // disable UNI ports/ONU
740 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
741 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000742 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000743 } else { //LockStateFSM already init
744 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000746 }
747 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000748 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000749 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000751 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
752 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000754 }
mpagenko01e726e2020-10-23 09:45:29 +0000755 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000756
757 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000759 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300760 }
761}
762
Himani Chawla6d2ae152020-09-02 13:11:20 +0530763//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
765 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000766
mpagenkofc4f56e2020-11-04 17:17:49 +0000767 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
768 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
769 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
770 // for real ONU's that should have nearly no influence
771 // Note that for real ONU's there is anyway a problematic situation with following sequence:
772 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
773 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
774 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
775 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
776
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000777 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000778 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000779 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000781 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000782 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000784 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300785}
786
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
788 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000789
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000791 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000793 return
794 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000796 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000798 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000800 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000801 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000802 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000803 }
Himani Chawla4d908332020-08-31 12:30:20 +0530804 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000805 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
806 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
807 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
808 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000810}
811
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
813 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000814
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000818 if !dh.isSkipOnuConfigReconciling() {
819 dh.stopReconciling(ctx)
820 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000821 return
822 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000823 dh.pOnuTP.lockTpProcMutex()
824 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000825 pDevEntry.persUniConfigMutex.RLock()
826 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000828 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000830 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000831 if !dh.isSkipOnuConfigReconciling() {
832 dh.stopReconciling(ctx)
833 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000834 return
835 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000836 techProfsFound := false
837 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000839 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
840 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000841 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000842 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000843 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000844 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000845 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800846 for tpID := range uniData.PersTpPathMap {
847 // deadline context to ensure completion of background routines waited for
848 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
849 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000851
Girish Gowdra041dcb32020-11-16 16:54:30 -0800852 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
853 var wg sync.WaitGroup
854 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
856 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800857 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800859 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000861 if len(uniData.PersFlowParams) != 0 {
862 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000863 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000864 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000865 if !techProfsFound {
866 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
867 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000868 if !dh.isSkipOnuConfigReconciling() {
869 dh.stopReconciling(ctx)
870 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000871 return
872 }
873 if dh.isSkipOnuConfigReconciling() {
874 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
875 }
876 if !flowsFound {
877 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
878 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000879 if !dh.isSkipOnuConfigReconciling() {
880 dh.stopReconciling(ctx)
881 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000882 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000883}
884
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
886 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000889 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000891 if !dh.isSkipOnuConfigReconciling() {
892 dh.stopReconciling(ctx)
893 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000894 return
895 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000896 pDevEntry.persUniConfigMutex.RLock()
897 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000898
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000899 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000901 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000902 if !dh.isSkipOnuConfigReconciling() {
903 dh.stopReconciling(ctx)
904 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000905 return
906 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000907 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000908 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000909 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
910 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000911 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000912 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000913 continue
914 }
915 if len(uniData.PersTpPathMap) == 0 {
916 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
917 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000918 // It doesn't make sense to configure any flows if no TPs are available
919 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000920 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000921 var uniPort *onuUniPort
922 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000924 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000925 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
926 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000927 if !dh.isSkipOnuConfigReconciling() {
928 dh.stopReconciling(ctx)
929 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000930 return
931 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000932 flowsFound = true
933 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000934 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000935 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000936 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000937 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000938 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000939 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000941 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
942 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000944 }
mpagenkof1fc3862021-02-16 10:09:52 +0000945 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000946 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000947 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000949 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000950 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000952 }
953 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000954 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000955 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000956 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
957 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
958 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000959 dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 }
961 if !flowsFound {
962 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
963 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000964 if !dh.isSkipOnuConfigReconciling() {
965 dh.stopReconciling(ctx)
966 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000967 return
968 }
969 if dh.isSkipOnuConfigReconciling() {
970 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000971 }
972}
973
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000974func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
975 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000976 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000977}
978
dbainbri4d3a0dc2020-12-02 00:33:42 +0000979func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
980 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000981
dbainbri4d3a0dc2020-12-02 00:33:42 +0000982 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000983 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000984 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000985 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000986 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000987 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000988
989 // deadline context to ensure completion of background routines waited for
990 //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 +0530991 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000993
994 pDevEntry.resetKvProcessingErrorIndication()
995
996 var wg sync.WaitGroup
997 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000998 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
999 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001000
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001001 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001002 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001003}
1004
mpagenko15ff4a52021-03-02 10:09:20 +00001005//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1006// before this change here return like this was used:
1007// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1008//was and is called in background - error return does not make sense
1009func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1010 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1011 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001013 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001014 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301016 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001018 return
Himani Chawla4d908332020-08-31 12:30:20 +05301019 }
mpagenko01e726e2020-10-23 09:45:29 +00001020
1021 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001023
dbainbri4d3a0dc2020-12-02 00:33:42 +00001024 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001025 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001026 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001027 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001028 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001029 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001030 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001031 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001032 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001033 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001034 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001035 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +00001036 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1037 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1038 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1039 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001040}
1041
mpagenkoc8bba412021-01-15 15:38:44 +00001042//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001043func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1044 apDownloadManager *adapterDownloadManager) error {
1045 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001046 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001047
1048 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001049 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1050 if pDevEntry == nil {
1051 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1052 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1053 }
1054
mpagenko80622a52021-02-09 16:53:23 +00001055 if dh.ReadyForSpecificOmciConfig {
mpagenko15ff4a52021-03-02 10:09:20 +00001056 var inactiveImageID uint16
1057 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1058 dh.lockUpgradeFsm.Lock()
1059 defer dh.lockUpgradeFsm.Unlock()
1060 if dh.pOnuUpradeFsm == nil {
1061 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1062 if err == nil {
1063 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1064 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1065 "device-id": dh.deviceID, "error": err})
1066 }
1067 } else {
1068 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001069 "device-id": dh.deviceID, "error": err})
1070 }
mpagenko15ff4a52021-03-02 10:09:20 +00001071 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1072 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1073 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1074 if pUpgradeStatemachine != nil {
1075 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1076 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1077 "device-id": dh.deviceID, "error": err})
1078 }
1079 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1080 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1081 // for now a second start of download should work again
1082 } else { //should never occur
1083 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1084 "device-id": dh.deviceID})
1085 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001086 }
mpagenko80622a52021-02-09 16:53:23 +00001087 }
mpagenko15ff4a52021-03-02 10:09:20 +00001088 } else {
1089 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1090 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001091 }
1092 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001093 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1094 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001095 }
1096 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001097}
1098
Himani Chawla6d2ae152020-09-02 13:11:20 +05301099// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001100// #####################################################################################
1101
1102// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301103// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001104
dbainbri4d3a0dc2020-12-02 00:33:42 +00001105func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1106 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 +00001107}
1108
1109// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001111
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001113 var err error
1114
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115 // populate what we know. rest comes later after mib sync
1116 dh.device.Root = false
1117 dh.device.Vendor = "OpenONU"
1118 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001119 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001120 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001122 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001123
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001124 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1126 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301127 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001128 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001130 log.Fields{"device-id": dh.deviceID})
1131 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132
Himani Chawla4d908332020-08-31 12:30:20 +05301133 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001134 dh.ponPortNumber = dh.device.ParentPortNo
1135
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001136 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1137 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1138 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001139 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001140 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301141 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001142
1143 /*
1144 self._pon = PonPort.create(self, self._pon_port_number)
1145 self._pon.add_peer(self.parent_id, self._pon_port_number)
1146 self.logger.debug('adding-pon-port-to-agent',
1147 type=self._pon.get_port().type,
1148 admin_state=self._pon.get_port().admin_state,
1149 oper_status=self._pon.get_port().oper_status,
1150 )
1151 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001152 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001154 var ponPortNo uint32 = 1
1155 if dh.ponPortNumber != 0 {
1156 ponPortNo = dh.ponPortNumber
1157 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001158
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001159 pPonPort := &voltha.Port{
1160 PortNo: ponPortNo,
1161 Label: fmt.Sprintf("pon-%d", ponPortNo),
1162 Type: voltha.Port_PON_ONU,
1163 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301164 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001165 PortNo: ponPortNo}}, // Peer port is parent's port number
1166 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001167 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1168 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001169 e.Cancel(err)
1170 return
1171 }
1172 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001174 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176}
1177
1178// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001179func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001180
dbainbri4d3a0dc2020-12-02 00:33:42 +00001181 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001182 var err error
1183 /*
1184 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1185 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1186 return nil
1187 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1189 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001190 e.Cancel(err)
1191 return
1192 }
1193
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001194 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001195 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001196 // reconcilement will be continued after mib download is done
1197 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001198
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001199 /*
1200 ############################################################################
1201 # Setup Alarm handler
1202 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1203 device.serial_number)
1204 ############################################################################
1205 # Setup PM configuration for this device
1206 # Pass in ONU specific options
1207 kwargs = {
1208 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1209 'heartbeat': self.heartbeat,
1210 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1211 }
1212 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1213 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1214 self.logical_device_id, device.serial_number,
1215 grouped=True, freq_override=False, **kwargs)
1216 pm_config = self._pm_metrics.make_proto()
1217 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1218 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1219 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1220
1221 # Note, ONU ID and UNI intf set in add_uni_port method
1222 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1223 ani_ports=[self._pon])
1224
1225 # Code to Run OMCI Test Action
1226 kwargs_omci_test_action = {
1227 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1228 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1229 }
1230 serial_number = device.serial_number
1231 self._test_request = OmciTestRequest(self.core_proxy,
1232 self.omci_agent, self.device_id,
1233 AniG, serial_number,
1234 self.logical_device_id,
1235 exclusive=False,
1236 **kwargs_omci_test_action)
1237
1238 self.enabled = True
1239 else:
1240 self.logger.info('onu-already-activated')
1241 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001242
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001244}
1245
1246// doStateConnected get the device info and update to voltha core
1247// for comparison of the original method (not that easy to uncomment): compare here:
1248// voltha-openolt-adapter/adaptercore/device_handler.go
1249// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001251
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301253 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001254 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001256}
1257
1258// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260
dbainbri4d3a0dc2020-12-02 00:33:42 +00001261 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301262 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001263 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001265
1266 /*
1267 // Synchronous call to update device state - this method is run in its own go routine
1268 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1269 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001270 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 +00001271 return err
1272 }
1273 return nil
1274 */
1275}
1276
1277// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001279
dbainbri4d3a0dc2020-12-02 00:33:42 +00001280 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001281 var err error
1282
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001283 device := dh.device
1284 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001285 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001287 e.Cancel(err)
1288 return
1289 }
1290
1291 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001293 /*
1294 // Update the all ports state on that device to disable
1295 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001296 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001297 return er
1298 }
1299
1300 //Update the device oper state and connection status
1301 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1302 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1303 dh.device = cloned
1304
1305 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001306 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001307 return er
1308 }
1309
1310 //get the child device for the parent device
1311 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1312 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001313 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001314 return err
1315 }
1316 for _, onuDevice := range onuDevices.Items {
1317
1318 // Update onu state as down in onu adapter
1319 onuInd := oop.OnuIndication{}
1320 onuInd.OperState = "down"
1321 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1322 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1323 if er != nil {
1324 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001325 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001326 //Do not return here and continue to process other ONUs
1327 }
1328 }
1329 // * Discovered ONUs entries need to be cleared , since after OLT
1330 // is up, it starts sending discovery indications again* /
1331 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001332 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001333 return nil
1334 */
Himani Chawla4d908332020-08-31 12:30:20 +05301335 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001336 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001337 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001338}
1339
Himani Chawla6d2ae152020-09-02 13:11:20 +05301340// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001341// #################################################################################
1342
1343// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301344// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001345
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001346//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001347func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001348 dh.lockDevice.RLock()
1349 pOnuDeviceEntry := dh.pOnuOmciDevice
1350 if aWait && pOnuDeviceEntry == nil {
1351 //keep the read sema short to allow for subsequent write
1352 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001353 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001354 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1355 // so it might be needed to wait here for that event with some timeout
1356 select {
1357 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001358 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001359 return nil
1360 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001361 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001362 // if written now, we can return the written value without sema
1363 return dh.pOnuOmciDevice
1364 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001365 }
mpagenko3af1f032020-06-10 08:53:41 +00001366 dh.lockDevice.RUnlock()
1367 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001368}
1369
Himani Chawla6d2ae152020-09-02 13:11:20 +05301370//setOnuDeviceEntry sets the ONU device entry within the handler
1371func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301372 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001373 dh.lockDevice.Lock()
1374 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001375 dh.pOnuOmciDevice = apDeviceEntry
1376 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001377 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301378 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001379}
1380
Himani Chawla6d2ae152020-09-02 13:11:20 +05301381//addOnuDeviceEntry creates a new ONU device or returns the existing
1382func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001383 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001384
dbainbri4d3a0dc2020-12-02 00:33:42 +00001385 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001386 if deviceEntry == nil {
1387 /* costum_me_map in python code seems always to be None,
1388 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1389 /* also no 'clock' argument - usage open ...*/
1390 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001391 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001392 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001393 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301394 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001395 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301396 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001397 // fire deviceEntry ready event to spread to possibly waiting processing
1398 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001400 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001402 }
1403 // might be updated with some error handling !!!
1404 return nil
1405}
1406
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1408 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001409 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1410
1411 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001412
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001414 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001415 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001416 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1417 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001418 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 if err := dh.storePersistentData(ctx); err != nil {
1420 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001421 log.Fields{"device-id": dh.deviceID, "err": err})
1422 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001424 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001426 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1427 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001429 }
1430 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001432 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001433
1434 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435 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 +00001436 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001437 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001438 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001439 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001440 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1441 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1442 // 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 +00001443 // 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 +00001444 // so let's just try to keep it simple ...
1445 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001447 if err != nil || device == nil {
1448 //TODO: needs to handle error scenarios
1449 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1450 return errors.New("Voltha Device not found")
1451 }
1452 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001453
dbainbri4d3a0dc2020-12-02 00:33:42 +00001454 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001455 return err
mpagenko3af1f032020-06-10 08:53:41 +00001456 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001457
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001458 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459
1460 /* this might be a good time for Omci Verify message? */
1461 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001462 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001463 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001464 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466
1467 /* give the handler some time here to wait for the OMCi verification result
1468 after Timeout start and try MibUpload FSM anyway
1469 (to prevent stopping on just not supported OMCI verification from ONU) */
1470 select {
1471 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001473 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001474 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001475 }
1476
1477 /* In py code it looks earlier (on activate ..)
1478 # Code to Run OMCI Test Action
1479 kwargs_omci_test_action = {
1480 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1481 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1482 }
1483 serial_number = device.serial_number
1484 self._test_request = OmciTestRequest(self.core_proxy,
1485 self.omci_agent, self.device_id,
1486 AniG, serial_number,
1487 self.logical_device_id,
1488 exclusive=False,
1489 **kwargs_omci_test_action)
1490 ...
1491 # Start test requests after a brief pause
1492 if not self._test_request_started:
1493 self._test_request_started = True
1494 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1495 reactor.callLater(tststart, self._test_request.start_collector)
1496
1497 */
1498 /* which is then: in omci_test_request.py : */
1499 /*
1500 def start_collector(self, callback=None):
1501 """
1502 Start the collection loop for an adapter if the frequency > 0
1503
1504 :param callback: (callable) Function to call to collect PM data
1505 """
1506 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1507 if callback is None:
1508 callback = self.perform_test_omci
1509
1510 if self.lc is None:
1511 self.lc = LoopingCall(callback)
1512
1513 if self.default_freq > 0:
1514 self.lc.start(interval=self.default_freq / 10)
1515
1516 def perform_test_omci(self):
1517 """
1518 Perform the initial test request
1519 """
1520 ani_g_entities = self._device.configuration.ani_g_entities
1521 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1522 is not None else None
1523 self._entity_id = ani_g_entities_ids[0]
1524 self.logger.info('perform-test', entity_class=self._entity_class,
1525 entity_id=self._entity_id)
1526 try:
1527 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1528 result = yield self._device.omci_cc.send(frame)
1529 if not result.fields['omci_message'].fields['success_code']:
1530 self.logger.info('Self-Test Submitted Successfully',
1531 code=result.fields[
1532 'omci_message'].fields['success_code'])
1533 else:
1534 raise TestFailure('Test Failure: {}'.format(
1535 result.fields['omci_message'].fields['success_code']))
1536 except TimeoutError as e:
1537 self.deferred.errback(failure.Failure(e))
1538
1539 except Exception as e:
1540 self.logger.exception('perform-test-Error', e=e,
1541 class_id=self._entity_class,
1542 entity_id=self._entity_id)
1543 self.deferred.errback(failure.Failure(e))
1544
1545 */
1546
1547 // PM related heartbeat??? !!!TODO....
1548 //self._heartbeat.enabled = True
1549
mpagenko1cc3cb42020-07-27 15:24:38 +00001550 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1551 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1552 * 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 +05301553 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001554 */
1555 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001556 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001557 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001558 if pMibUlFsm.Is(ulStDisabled) {
1559 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 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 +00001561 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301562 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301564 //Determine ONU status and start/re-start MIB Synchronization tasks
1565 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001566 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301567 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 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 +00001569 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570 }
Himani Chawla4d908332020-08-31 12:30:20 +05301571 } else {
1572 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573 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 +00001574 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301575 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001576 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001577 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001578 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001580 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001581 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001582 }
1583 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001585 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001586 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001587
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001588 if !dh.getCollectorIsRunning() {
1589 // Start PM collector routine
1590 go dh.startCollector(ctx)
1591 }
Himani Chawla1472c682021-03-17 17:11:14 +05301592 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301593 go dh.startAlarmManager(ctx)
1594 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301595
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001596 return nil
1597}
1598
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001600 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001601 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001602 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001604
mpagenko900ee4b2020-10-12 11:56:34 +00001605 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1606 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1607 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001608 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001609 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001610 log.Fields{"device-id": dh.deviceID, "error": err})
1611 // abort: system behavior is just unstable ...
1612 return err
1613 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001614 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 _ = 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 +00001616
1617 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1618 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1619 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001621 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001623 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001624 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001626
1627 //TODO!!! remove existing traffic profiles
1628 /* from py code, if TP's exist, remove them - not yet implemented
1629 self._tp = dict()
1630 # Let TP download happen again
1631 for uni_id in self._tp_service_specific_task:
1632 self._tp_service_specific_task[uni_id].clear()
1633 for uni_id in self._tech_profile_download_done:
1634 self._tech_profile_download_done[uni_id].clear()
1635 */
1636
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001638
mpagenkofc4f56e2020-11-04 17:17:49 +00001639 dh.ReadyForSpecificOmciConfig = false
1640
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001642 // abort: system behavior is just unstable ...
1643 return err
1644 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001646 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001648 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001649 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001651 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001652 // abort: system behavior is just unstable ...
1653 return err
1654 }
1655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001657 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658 return nil
1659}
1660
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001661func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001662 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1663 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1664 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1665 // and using the stop/reset event should never harm
1666
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001668 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001670 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1671 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001672 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001673 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001674 }
1675 //MibDownload may run
1676 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1677 if pMibDlFsm != nil {
1678 _ = pMibDlFsm.Event(dlEvReset)
1679 }
1680 //port lock/unlock FSM's may be active
1681 if dh.pUnlockStateFsm != nil {
1682 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1683 }
1684 if dh.pLockStateFsm != nil {
1685 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1686 }
1687 //techProfile related PonAniConfigFsm FSM may be active
1688 if dh.pOnuTP != nil {
1689 // should always be the case here
1690 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1691 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001692 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001693 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001694 }
mpagenko900ee4b2020-10-12 11:56:34 +00001695 }
1696 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001697 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001698 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001699 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1700 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001701 dh.lockVlanConfig.RUnlock()
1702 //reset of all Fsm is always accompanied by global persistency data removal
1703 // no need to remove specific data
1704 pVlanFilterFsm.RequestClearPersistency(false)
1705 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001706 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001707 } else {
1708 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001709 }
1710 }
1711 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001712 if dh.getCollectorIsRunning() {
1713 // Stop collector routine
1714 dh.stopCollector <- true
1715 }
Himani Chawla1472c682021-03-17 17:11:14 +05301716 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301717 dh.stopAlarmManager <- true
1718 }
1719
mpagenko80622a52021-02-09 16:53:23 +00001720 //reset a possibly running upgrade FSM
1721 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1722 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1723 dh.lockUpgradeFsm.RLock()
1724 if dh.pOnuUpradeFsm != nil {
mpagenko59498c12021-03-18 14:15:15 +00001725 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1726 if pUpgradeStatemachine != nil {
1727 if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
1728 dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
1729 }
1730 _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
1731 }
1732 //else the FSM seems already to be in some released state
mpagenko80622a52021-02-09 16:53:23 +00001733 }
1734 dh.lockUpgradeFsm.RUnlock()
1735
mpagenko7d6bb022021-03-11 15:07:55 +00001736 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001737 return nil
1738}
1739
dbainbri4d3a0dc2020-12-02 00:33:42 +00001740func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1741 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 +05301742
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001743 // store persistent data collected during MIB upload processing
1744 if err := dh.storePersistentData(ctx); err != nil {
1745 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1746 log.Fields{"device-id": dh.deviceID, "err": err})
1747 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001748 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001749 dh.addAllUniPorts(ctx)
1750
mpagenkoa40e99a2020-11-17 13:50:39 +00001751 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1752 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1753 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1754 * disable/enable toggling here to allow traffic
1755 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1756 * like the py comment says:
1757 * # start by locking all the unis till mib sync and initial mib is downloaded
1758 * # this way we can capture the port down/up events when we are ready
1759 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301760
mpagenkoa40e99a2020-11-17 13:50:39 +00001761 // Init Uni Ports to Admin locked state
1762 // *** should generate UniLockStateDone event *****
1763 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001765 } else { //LockStateFSM already init
1766 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001768 }
1769}
1770
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1772 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301773 /* Mib download procedure -
1774 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1775 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001777 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001778 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001779 return
1780 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301781 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1782 if pMibDlFsm != nil {
1783 if pMibDlFsm.Is(dlStDisabled) {
1784 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 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 +05301786 // maybe try a FSM reset and then again ... - TODO!!!
1787 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301789 // maybe use more specific states here for the specific download steps ...
1790 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301792 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301794 //Begin MIB data download (running autonomously)
1795 }
1796 }
1797 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001799 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301800 // maybe try a FSM reset and then again ... - TODO!!!
1801 }
1802 /***** Mib download started */
1803 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301805 }
1806}
1807
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1809 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301810 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001811 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001812 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001813 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001814 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1815 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1816 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1817 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301819 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1820 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301822 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301824 }
1825 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301827 log.Fields{"device-id": dh.deviceID})
1828 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001829 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001830
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07001831 if !dh.getCollectorIsRunning() {
1832 // Start PM collector routine
1833 go dh.startCollector(ctx)
1834 }
1835 if !dh.getAlarmManagerIsRunning(ctx) {
1836 go dh.startAlarmManager(ctx)
1837 }
1838
Girish Gowdrae0140f02021-02-02 16:55:09 -08001839 // Initialize classical L2 PM Interval Counters
1840 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1841 // There is no way we should be landing here, but if we do then
1842 // there is nothing much we can do about this other than log error
1843 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1844 }
1845
mpagenkofc4f56e2020-11-04 17:17:49 +00001846 dh.ReadyForSpecificOmciConfig = true
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001847
1848 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1849 if pDevEntry == nil {
1850 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1851 return
1852 }
1853 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
1854 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1855 log.Fields{"device-id": dh.deviceID})
1856 go dh.reconcileDeviceTechProf(ctx)
1857 // reconcilement will be continued after ani config is done
1858 } else {
1859 // *** should generate UniUnlockStateDone event *****
1860 if dh.pUnlockStateFsm == nil {
1861 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1862 } else { //UnlockStateFSM already init
1863 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1864 dh.runUniLockFsm(ctx, false)
1865 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301866 }
1867}
1868
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1870 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301871
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001872 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301874 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1876 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001877 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001879 return
1880 }
1881 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 if err := dh.storePersistentData(ctx); err != nil {
1883 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001884 log.Fields{"device-id": dh.deviceID, "err": err})
1885 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301886 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 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 +05301888 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001890 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301891 }
1892}
1893
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1895 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001896 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001898 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1899 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001901 }
1902
dbainbri4d3a0dc2020-12-02 00:33:42 +00001903 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001904 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001906
1907 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001909
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001911 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001912 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001913 return
1914 }
1915 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 if err := dh.storePersistentData(ctx); err != nil {
1917 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001918 log.Fields{"device-id": dh.deviceID, "err": err})
1919 }
mpagenko900ee4b2020-10-12 11:56:34 +00001920}
1921
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1923 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001924 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001926 voltha.OperStatus_ACTIVE); err != nil {
1927 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001929 }
1930
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001932 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001933 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001935
1936 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001938
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001940 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001942 return
1943 }
1944 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 if err := dh.storePersistentData(ctx); err != nil {
1946 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001947 log.Fields{"device-id": dh.deviceID, "err": err})
1948 }
mpagenko900ee4b2020-10-12 11:56:34 +00001949}
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001952 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001954 // attention: the device reason update is done based on ONU-UNI-Port related activity
1955 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001956 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001957 // 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 +00001958 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301959 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001960 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001962 }
1963 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001965 // attention: the device reason update is done based on ONU-UNI-Port related activity
1966 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001967 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001968 // 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 +00001969 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001970 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001971 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301972}
1973
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1975 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001976 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301977 // attention: the device reason update is done based on ONU-UNI-Port related activity
1978 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301979
mpagenkof1fc3862021-02-16 10:09:52 +00001980 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001981 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001982 // which may be the case from some previous actvity on another UNI Port of the ONU
1983 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001984 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1985 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001986 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001987 }
1988 }
1989 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001990 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001991 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001993 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301994 }
mpagenkof1fc3862021-02-16 10:09:52 +00001995
1996 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1997 //events that request KvStore write
1998 if err := dh.storePersistentData(ctx); err != nil {
1999 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2000 log.Fields{"device-id": dh.deviceID, "err": err})
2001 }
2002 } else {
2003 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2004 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002005 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302006}
2007
Himani Chawla6d2ae152020-09-02 13:11:20 +05302008//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302010 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002011 case MibDatabaseSync:
2012 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002014 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002015 case UniLockStateDone:
2016 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002017 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002018 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002019 case MibDownloadDone:
2020 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002022 }
2023 case UniUnlockStateDone:
2024 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002026 }
mpagenko900ee4b2020-10-12 11:56:34 +00002027 case UniEnableStateDone:
2028 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002029 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002030 }
2031 case UniDisableStateDone:
2032 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002034 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002035 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002036 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002037 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002038 }
mpagenkof1fc3862021-02-16 10:09:52 +00002039 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002040 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002042 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002043 default:
2044 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002045 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002046 }
2047 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002048}
2049
dbainbri4d3a0dc2020-12-02 00:33:42 +00002050func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002051 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302053 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002054 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002056 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302057 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002059 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002061 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002062 //store UniPort with the System-PortNumber key
2063 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002064 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002065 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2067 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002068 } //error logging already within UniPort method
2069 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002071 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002072 }
2073 }
2074}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002075
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002076func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2077 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2078 if pDevEntry == nil {
2079 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2080 return
2081 }
2082 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2083 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2084 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2085 for _, mgmtEntityID := range pptpInstKeys {
2086 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2087 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2088 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2089 i++
2090 }
2091 } else {
2092 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2093 }
2094 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2095 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2096 for _, mgmtEntityID := range veipInstKeys {
2097 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2098 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2099 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2100 i++
2101 }
2102 } else {
2103 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2104 }
2105 if i == 0 {
2106 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2107 }
2108}
2109
mpagenko3af1f032020-06-10 08:53:41 +00002110// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002112 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302113 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002114 // with following remark:
2115 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2116 // # load on the core
2117
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002118 // 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 +00002119
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002120 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002121 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302122 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302124 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002125 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002126 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 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 +00002128 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002130 }
mpagenko3af1f032020-06-10 08:53:41 +00002131 }
2132 }
2133}
2134
2135// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002137 // compare enableUniPortStateUpdate() above
2138 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2139 for uniNo, uniPort := range dh.uniEntityMap {
2140 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302141 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302143 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002144 if !dh.isReconciling() {
2145 //maybe also use getter functions on uniPort - perhaps later ...
2146 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2147 } else {
2148 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2149 }
2150
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002151 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002152 }
2153}
2154
2155// ONU_Active/Inactive announcement on system KAFKA bus
2156// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002158 var de voltha.DeviceEvent
2159 eventContext := make(map[string]string)
2160 //Populating event context
2161 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002162 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002163 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302165 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002166 }
2167 oltSerialNumber := parentDevice.SerialNumber
2168
2169 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2170 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2171 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302172 eventContext["olt-serial-number"] = oltSerialNumber
2173 eventContext["device-id"] = aDeviceID
2174 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002176 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002177
2178 /* Populating device event body */
2179 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302180 de.ResourceId = aDeviceID
2181 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002182 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2183 de.Description = fmt.Sprintf("%s Event - %s - %s",
2184 cEventObjectType, cOnuActivatedEvent, "Raised")
2185 } else {
2186 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2187 de.Description = fmt.Sprintf("%s Event - %s - %s",
2188 cEventObjectType, cOnuActivatedEvent, "Cleared")
2189 }
2190 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2192 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302193 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002194 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302196 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002197}
2198
Himani Chawla4d908332020-08-31 12:30:20 +05302199// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002201 chLSFsm := make(chan Message, 2048)
2202 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302203 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002205 sFsmName = "LockStateFSM"
2206 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002208 sFsmName = "UnLockStateFSM"
2209 }
mpagenko3af1f032020-06-10 08:53:41 +00002210
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002212 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002214 return
2215 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002217 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002218 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302219 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002220 dh.pLockStateFsm = pLSFsm
2221 } else {
2222 dh.pUnlockStateFsm = pLSFsm
2223 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002225 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002227 }
2228}
2229
2230// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002232 /* Uni Port lock/unlock procedure -
2233 ***** should run via 'adminDone' state and generate the argument requested event *****
2234 */
2235 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302236 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002237 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2238 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2239 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002240 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302241 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002242 }
2243 } else {
2244 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2245 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2246 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002247 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302248 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002249 }
2250 }
2251 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002252 if pLSStatemachine.Is(uniStDisabled) {
2253 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002254 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002255 // maybe try a FSM reset and then again ... - TODO!!!
2256 } else {
2257 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002259 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002260 }
2261 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002263 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002264 // maybe try a FSM reset and then again ... - TODO!!!
2265 }
2266 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002267 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002268 // maybe try a FSM reset and then again ... - TODO!!!
2269 }
2270}
2271
mpagenko80622a52021-02-09 16:53:23 +00002272// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002273func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002274 //in here lockUpgradeFsm is already locked
2275 chUpgradeFsm := make(chan Message, 2048)
2276 var sFsmName = "OnuSwUpgradeFSM"
2277 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002278 if apDevEntry.PDevOmciCC == nil {
2279 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2280 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002281 }
mpagenko15ff4a52021-03-02 10:09:20 +00002282 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002283 sFsmName, chUpgradeFsm)
2284 if dh.pOnuUpradeFsm != nil {
2285 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2286 if pUpgradeStatemachine != nil {
2287 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2288 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2289 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2290 // maybe try a FSM reset and then again ... - TODO!!!
2291 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2292 }
2293 /***** LockStateFSM started */
2294 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2295 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2296 } else {
2297 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2298 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2299 // maybe try a FSM reset and then again ... - TODO!!!
2300 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2301 }
2302 } else {
2303 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2304 // maybe try a FSM reset and then again ... - TODO!!!
2305 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2306 }
2307 } else {
2308 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2309 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2310 }
2311 return nil
2312}
2313
2314// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2315func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2316 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2317 "device-id": dh.deviceID})
2318 dh.lockUpgradeFsm.Lock()
2319 defer dh.lockUpgradeFsm.Unlock()
2320 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2321}
2322
mpagenko15ff4a52021-03-02 10:09:20 +00002323// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2324func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2325 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2326 if pDevEntry == nil {
2327 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2328 return
2329 }
2330
2331 dh.lockUpgradeFsm.RLock()
2332 defer dh.lockUpgradeFsm.RUnlock()
2333 if dh.pOnuUpradeFsm != nil {
2334 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2335 if pUpgradeStatemachine != nil {
2336 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2337 // (some manual forced commit could do without)
2338 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002339 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002340 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2341 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2342 return
2343 }
2344 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2345 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2346 } else {
2347 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2348 log.Fields{"device-id": dh.deviceID})
2349 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2350 return
2351 }
2352 }
2353 }
2354 } else {
2355 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2356 }
2357}
2358
Himani Chawla6d2ae152020-09-02 13:11:20 +05302359//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002360func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002361
2362 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002363 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002364 kvbackend := &db.Backend{
2365 Client: dh.pOpenOnuAc.kvClient,
2366 StoreType: dh.pOpenOnuAc.KVStoreType,
2367 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002368 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002369 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2370 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002371
mpagenkoaf801632020-07-03 10:00:42 +00002372 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002373}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302375 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002376
mpagenkodff5dda2020-08-28 11:52:01 +00002377 for _, field := range flow.GetOfbFields(apFlowItem) {
2378 switch field.Type {
2379 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2380 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002381 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002382 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2383 }
mpagenko01e726e2020-10-23 09:45:29 +00002384 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002385 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2386 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302387 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002388 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302389 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2390 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002391 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2392 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002393 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2394 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302395 return
mpagenkodff5dda2020-08-28 11:52:01 +00002396 }
2397 }
mpagenko01e726e2020-10-23 09:45:29 +00002398 */
mpagenkodff5dda2020-08-28 11:52:01 +00002399 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2400 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302401 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002402 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302403 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002404 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302405 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002406 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002407 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302408 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002409 }
2410 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2411 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302412 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002413 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002414 "PCP": loAddPcp})
2415 }
2416 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2417 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002419 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2420 }
2421 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2422 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002424 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2425 }
2426 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2427 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002429 "IPv4-DST": field.GetIpv4Dst()})
2430 }
2431 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2432 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002433 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002434 "IPv4-SRC": field.GetIpv4Src()})
2435 }
2436 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2437 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002438 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002439 "Metadata": field.GetTableMetadata()})
2440 }
2441 /*
2442 default:
2443 {
2444 //all other entires ignored
2445 }
2446 */
2447 }
2448 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302449}
mpagenkodff5dda2020-08-28 11:52:01 +00002450
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002452 for _, action := range flow.GetActions(apFlowItem) {
2453 switch action.Type {
2454 /* not used:
2455 case of.OfpActionType_OFPAT_OUTPUT:
2456 {
mpagenko01e726e2020-10-23 09:45:29 +00002457 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002458 "Output": action.GetOutput()})
2459 }
2460 */
2461 case of.OfpActionType_OFPAT_PUSH_VLAN:
2462 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002464 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2465 }
2466 case of.OfpActionType_OFPAT_SET_FIELD:
2467 {
2468 pActionSetField := action.GetSetField()
2469 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002470 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002471 "OxcmClass": pActionSetField.Field.OxmClass})
2472 }
2473 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302474 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302476 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002477 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302478 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302480 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002481 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002482 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002483 "Type": pActionSetField.Field.GetOfbField().Type})
2484 }
2485 }
2486 /*
2487 default:
2488 {
2489 //all other entires ignored
2490 }
2491 */
2492 }
2493 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302494}
2495
2496//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302498 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2499 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2500 var loAddPcp, loSetPcp uint8
2501 var loIPProto uint32
2502 /* the TechProfileId is part of the flow Metadata - compare also comment within
2503 * OLT-Adapter:openolt_flowmgr.go
2504 * Metadata 8 bytes:
2505 * Most Significant 2 Bytes = Inner VLAN
2506 * Next 2 Bytes = Tech Profile ID(TPID)
2507 * Least Significant 4 Bytes = Port ID
2508 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2509 * subscriber related flows.
2510 */
2511
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302513 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002514 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302515 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002516 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302517 }
mpagenko551a4d42020-12-08 18:09:20 +00002518 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002519 loCookie := apFlowItem.GetCookie()
2520 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002521 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002522 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302523
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002525 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302526 if loIPProto == 2 {
2527 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2528 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002529 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2530 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302531 return nil
2532 }
mpagenko01e726e2020-10-23 09:45:29 +00002533 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002535
2536 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002537 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002538 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2539 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2540 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2541 //TODO!!: Use DeviceId within the error response to rwCore
2542 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002543 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002544 }
2545 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002547 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2548 } else {
2549 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2550 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2551 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302552 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002553 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002554 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002555 }
mpagenko9a304ea2020-12-16 15:54:01 +00002556
2557 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002558 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002559 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302560 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002561 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002562 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002563 dh.lockVlanConfig.RUnlock()
2564 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002565 }
mpagenkof1fc3862021-02-16 10:09:52 +00002566 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002567 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002568 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002569}
2570
2571//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002572func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002573 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2574 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2575 //no extra check is done on the rule parameters
2576 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2577 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2578 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2579 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002580 // - 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 +00002581 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002582 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002583
2584 /* TT related temporary workaround - should not be needed anymore
2585 for _, field := range flow.GetOfbFields(apFlowItem) {
2586 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2587 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002588 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002589 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2590 if loIPProto == 2 {
2591 // 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 +00002592 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002593 log.Fields{"device-id": dh.deviceID})
2594 return nil
2595 }
2596 }
2597 } //for all OfbFields
2598 */
2599
mpagenko9a304ea2020-12-16 15:54:01 +00002600 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002601 dh.lockVlanConfig.RLock()
2602 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002603 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002604 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002605 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002607 log.Fields{"device-id": dh.deviceID})
2608 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002609 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002610 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002611
mpagenko01e726e2020-10-23 09:45:29 +00002612 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002613}
2614
Himani Chawla26e555c2020-08-31 12:30:20 +05302615// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002616// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002617func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002618 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002619 chVlanFilterFsm := make(chan Message, 2048)
2620
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002622 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302624 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002625 }
2626
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002628 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2629 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002630 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002631 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002632 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2633 // (from parallel processing)
2634 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302635 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002636 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2637 if pVlanFilterStatemachine != nil {
2638 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2639 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302641 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002642 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302643 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002644 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302645 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2646 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002647 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002648 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002649 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302650 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002651 }
2652 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002653 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002654 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302655 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002656 }
2657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002658 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002659 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302660 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002661 }
2662 return nil
2663}
2664
mpagenkofc4f56e2020-11-04 17:17:49 +00002665//VerifyVlanConfigRequest checks on existence of a given uniPort
2666// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002667func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002668 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2669 var pCurrentUniPort *onuUniPort
2670 for _, uniPort := range dh.uniEntityMap {
2671 // only if this port is validated for operState transfer
2672 if uniPort.uniID == uint8(aUniID) {
2673 pCurrentUniPort = uniPort
2674 break //found - end search loop
2675 }
2676 }
2677 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002678 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002679 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2680 return
2681 }
mpagenko551a4d42020-12-08 18:09:20 +00002682 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002683}
2684
mpagenkodff5dda2020-08-28 11:52:01 +00002685//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002686func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002687 //TODO!! verify and start pending flow configuration
2688 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2689 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002690
2691 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302692 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002693 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002694 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2695 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2696 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002697 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2698 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2699 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2700 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2701 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2702 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2703 } else {
2704 /***** UniVlanConfigFsm continued */
2705 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2706 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2707 "UniPort": apUniPort.portNo})
2708 }
2709 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2710 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2711 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2712 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2713 } else {
2714 /***** UniVlanConfigFsm continued */
2715 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2716 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2717 "UniPort": apUniPort.portNo})
2718 }
mpagenkodff5dda2020-08-28 11:52:01 +00002719 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002720 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2721 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002722 "UniPort": apUniPort.portNo})
2723 }
2724 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002725 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2726 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2727 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002728 }
2729 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002730 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002731 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002732 }
mpagenkof1fc3862021-02-16 10:09:52 +00002733 } else {
2734 dh.lockVlanConfig.RUnlock()
2735 }
mpagenkodff5dda2020-08-28 11:52:01 +00002736}
2737
2738//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2739// 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 +00002740func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2741 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002742 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2743 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002744 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302745 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002746 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002747}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002748
Girish Gowdra26a40922021-01-29 17:14:34 -08002749//ProcessPendingTpDelete processes any pending TP delete (if available)
2750func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2751 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2752 if apUniPort == nil {
2753 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2754 return
2755 }
2756 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2757 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2758 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2759 if pAniConfigStatemachine != nil {
2760 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2761 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2762 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2763 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2764 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2765 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2766 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2767 return
2768 }
2769 } else {
2770 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2771 return
2772 }
2773 }
2774 return
2775 }
2776}
2777
mpagenkof1fc3862021-02-16 10:09:52 +00002778//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2779func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2780 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2781 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2782 // obviously then parallel processing on the cancel must be avoided
2783 // deadline context to ensure completion of background routines waited for
2784 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2785 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2786 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2787
2788 aPDevEntry.resetKvProcessingErrorIndication()
2789 var wg sync.WaitGroup
2790 wg.Add(1) // for the 1 go routine to finish
2791
2792 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2793 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2794
2795 return aPDevEntry.getKvProcessingErrorIndication()
2796}
2797
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002798//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2799//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002800func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2801 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002802
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002803 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002805 return nil
2806 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002808
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002810 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002812 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2813 }
2814 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2815
mpagenkof1fc3862021-02-16 10:09:52 +00002816 if aWriteToKvStore {
2817 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2818 }
2819 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002820}
2821
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002823 defer cancel() //ensure termination of context (may be pro forma)
2824 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002825 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002826 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002827}
2828
dbainbri4d3a0dc2020-12-02 00:33:42 +00002829func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002830
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002831 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002832 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002833 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002834 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2835 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002836 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002837 return err
2838 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002840 return nil
2841 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002842 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002843 return nil
2844}
2845
dbainbri4d3a0dc2020-12-02 00:33:42 +00002846func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2847 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002848 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002849 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002850 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2851 }
mpagenkof1fc3862021-02-16 10:09:52 +00002852 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002853}
2854
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002855func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2856 var errStr string = ""
2857 for _, err := range errS {
2858 if err != nil {
2859 errStr = errStr + err.Error() + " "
2860 }
2861 }
2862 if errStr != "" {
2863 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2864 }
2865 return nil
2866}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867
2868// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2869func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2870 dh.lockDevice.RLock()
2871 defer dh.lockDevice.RUnlock()
2872 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2873 return uniPort.entityID, nil
2874 }
2875 return 0, errors.New("error-fetching-uni-port")
2876}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002877
2878// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002879func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2880 var errorsList []error
2881 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 -08002882
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002883 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2884 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2885 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2886
2887 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2888 // successfully.
2889 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2890 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2891 if len(errorsList) > 0 {
2892 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2893 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002894 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002895 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2896 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002897}
2898
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002899func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2900 var err error
2901 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002902 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002903
2904 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2905 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2906 errorsList = append(errorsList, err)
2907 }
2908 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002909 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002910
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002911 return errorsList
2912}
2913
2914func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2915 var err error
2916 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002917 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002918 // Check if group metric related config is updated
2919 for _, v := range pmConfigs.Groups {
2920 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2921 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2922 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2923
2924 if ok && m.frequency != v.GroupFreq {
2925 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2926 errorsList = append(errorsList, err)
2927 }
2928 }
2929 if ok && m.enabled != v.Enabled {
2930 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2931 errorsList = append(errorsList, err)
2932 }
2933 }
2934 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002935 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002936 return errorsList
2937}
2938
2939func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2940 var err error
2941 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002942 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002943 // Check if standalone metric related config is updated
2944 for _, v := range pmConfigs.Metrics {
2945 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002946 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002947 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2948
2949 if ok && m.frequency != v.SampleFreq {
2950 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2951 errorsList = append(errorsList, err)
2952 }
2953 }
2954 if ok && m.enabled != v.Enabled {
2955 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2956 errorsList = append(errorsList, err)
2957 }
2958 }
2959 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002960 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002961 return errorsList
2962}
2963
2964// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002965func (dh *deviceHandler) startCollector(ctx context.Context) {
2966 logger.Debugf(ctx, "startingCollector")
2967
2968 // Start routine to process OMCI GET Responses
2969 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002970 // Initialize the next metric collection time.
2971 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2972 // reset like onu rebooted.
2973 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002974 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002975 for {
2976 select {
2977 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002978 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002979 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002980 // Stop the L2 PM FSM
2981 go func() {
2982 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2983 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2984 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2985 }
2986 } else {
2987 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2988 }
2989 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002990 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2991 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2992 }
2993 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2994 dh.pOnuMetricsMgr.stopTicks <- true
2995 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002996
Girish Gowdrae09a6202021-01-12 18:10:59 -08002997 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002998 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2999 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3000 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3001 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3002 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003003 // Update the next metric collection time.
3004 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003005 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003006 } else {
3007 if dh.pmConfigs.Grouped { // metrics are managed as a group
3008 // parse through the group and standalone metrics to see it is time to collect their metrics
3009 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003010
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003011 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3012 // 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 -08003013 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3014 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003015 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3016 }
3017 }
3018 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3019 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3020 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3021 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3022 }
3023 }
3024 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3025
3026 // parse through the group and update the next metric collection time
3027 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3028 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3029 // 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 -08003030 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3031 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003032 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3033 }
3034 }
3035 // parse through the standalone metrics and update the next metric collection time
3036 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3037 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3038 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3039 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3040 }
3041 }
3042 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3043 } /* else { // metrics are not managed as a group
3044 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3045 } */
3046 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003047 }
3048 }
3049}
kesavandfdf77632021-01-26 23:40:33 -05003050
3051func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3052
3053 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3054 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3055}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003056
mpagenkof1fc3862021-02-16 10:09:52 +00003057func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3058 if pFsm == nil {
3059 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003060 }
mpagenkof1fc3862021-02-16 10:09:52 +00003061 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003062}
3063
mpagenkof1fc3862021-02-16 10:09:52 +00003064func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3065 var pFsm *fsm.FSM
3066 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3067 switch omciFsm {
3068 case cUploadFsm:
3069 {
3070 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3071 }
3072 case cDownloadFsm:
3073 {
3074 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3075 }
3076 case cUniLockFsm:
3077 {
3078 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3079 }
3080 case cUniUnLockFsm:
3081 {
3082 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3083 }
3084 case cL2PmFsm:
3085 {
3086 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3087 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3088 } else {
3089 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003090 }
3091 }
mpagenko80622a52021-02-09 16:53:23 +00003092 case cOnuUpgradeFsm:
3093 {
3094 dh.lockUpgradeFsm.RLock()
3095 defer dh.lockUpgradeFsm.RUnlock()
3096 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3097 }
mpagenkof1fc3862021-02-16 10:09:52 +00003098 default:
3099 {
3100 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3101 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3102 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003103 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003104 }
mpagenkof1fc3862021-02-16 10:09:52 +00003105 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003106}
3107
mpagenkof1fc3862021-02-16 10:09:52 +00003108func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3109 for _, v := range dh.pOnuTP.pAniConfigFsm {
3110 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003111 return false
3112 }
3113 }
3114 return true
3115}
3116
mpagenkof1fc3862021-02-16 10:09:52 +00003117func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3118 dh.lockVlanConfig.RLock()
3119 defer dh.lockVlanConfig.RUnlock()
3120 for _, v := range dh.UniVlanConfigFsmMap {
3121 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3122 return false
3123 }
3124 }
3125 return true //FSM not active - so there is no activity on omci
3126}
3127
3128func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3129 dh.lockVlanConfig.RLock()
3130 defer dh.lockVlanConfig.RUnlock()
3131 for _, v := range dh.UniVlanConfigFsmMap {
3132 if v.pAdaptFsm.pFsm != nil {
3133 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3134 return true //there is at least one VLAN FSM with some active configuration
3135 }
3136 }
3137 }
3138 return false //there is no VLAN FSM with some active configuration
3139}
3140
3141func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3142 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3143 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3144 return false
3145 }
3146 }
3147 // a further check is done to identify, if at least some data traffic related configuration exists
3148 // 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])
3149 return dh.checkUserServiceExists(ctx)
3150}
3151
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003152func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3153 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3154 if err := dh.resetFsms(ctx, false); err != nil {
3155 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3156 // TODO: fatal error reset ONU, delete deviceHandler!
3157 return
3158 }
3159 if !dh.getCollectorIsRunning() {
3160 // Start PM collector routine
3161 go dh.startCollector(ctx)
3162 }
Himani Chawla1472c682021-03-17 17:11:14 +05303163 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303164 go dh.startAlarmManager(ctx)
3165 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003166 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003167 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003168}
3169
3170func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3171 dh.mutexCollectorFlag.Lock()
3172 dh.collectorIsRunning = flagValue
3173 dh.mutexCollectorFlag.Unlock()
3174}
3175
3176func (dh *deviceHandler) getCollectorIsRunning() bool {
3177 dh.mutexCollectorFlag.RLock()
3178 flagValue := dh.collectorIsRunning
3179 dh.mutexCollectorFlag.RUnlock()
3180 return flagValue
3181}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303182
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303183func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3184 dh.mutextAlarmManagerFlag.Lock()
3185 dh.alarmManagerIsRunning = flagValue
3186 dh.mutextAlarmManagerFlag.Unlock()
3187}
3188
Himani Chawla1472c682021-03-17 17:11:14 +05303189func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303190 dh.mutextAlarmManagerFlag.RLock()
3191 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303192 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303193 dh.mutextAlarmManagerFlag.RUnlock()
3194 return flagValue
3195}
3196
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303197func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3198 logger.Debugf(ctx, "startingAlarmManager")
3199
3200 // Start routine to process OMCI GET Responses
3201 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303202 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303203 if stop := <-dh.stopAlarmManager; stop {
3204 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303205 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303206 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303207 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3208 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3209 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303210 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303211 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303212 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3213 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303214 }
3215}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003216
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003217func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
3218 logger.Debugw(ctx, "start reconciling", log.Fields{"withOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
3219
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003220 if !dh.isReconciling() {
3221 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003222 logger.Debugw(ctx, "wait for channel signal or timeout",
3223 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003224 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003225 case success := <-dh.chReconcilingFinished:
3226 if success {
3227 logger.Debugw(ctx, "reconciling has been finished in time",
3228 log.Fields{"device-id": dh.deviceID})
3229 } else {
3230 logger.Debugw(ctx, "wait for reconciling aborted",
3231 log.Fields{"device-id": dh.deviceID})
3232 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003233 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003234 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3235 log.Fields{"device-id": dh.deviceID})
3236 }
3237 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003238 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003239 dh.mutexReconcilingFlag.Unlock()
3240 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003241 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003242 dh.mutexReconcilingFlag.Lock()
3243 if skipOnuConfig {
3244 dh.reconciling = cSkipOnuConfigReconciling
3245 } else {
3246 dh.reconciling = cOnuConfigReconciling
3247 }
3248 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003249}
3250
3251func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3252 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3253 if dh.isReconciling() {
3254 dh.chReconcilingFinished <- true
3255 } else {
3256 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3257 }
3258}
3259
3260func (dh *deviceHandler) isReconciling() bool {
3261 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003262 defer dh.mutexReconcilingFlag.RUnlock()
3263 return dh.reconciling != cNoReconciling
3264}
3265
3266func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3267 dh.mutexReconcilingFlag.RLock()
3268 defer dh.mutexReconcilingFlag.RUnlock()
3269 return dh.reconciling == cSkipOnuConfigReconciling
3270}
3271
3272func (dh *deviceHandler) setDeviceReason(value uint8) {
3273 dh.mutexDeviceReason.Lock()
3274 dh.deviceReason = value
3275 dh.mutexDeviceReason.Unlock()
3276}
3277
3278func (dh *deviceHandler) getDeviceReason() uint8 {
3279 dh.mutexDeviceReason.RLock()
3280 value := dh.deviceReason
3281 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003282 return value
3283}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003284
3285func (dh *deviceHandler) getDeviceReasonString() string {
3286 return deviceReasonMap[dh.getDeviceReason()]
3287}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003288
3289func (dh *deviceHandler) setReconcilingFlows(value bool) {
3290 dh.mutexReconcilingFlowsFlag.Lock()
3291 dh.reconcilingFlows = value
3292 dh.mutexReconcilingFlowsFlag.Unlock()
3293}
3294
3295func (dh *deviceHandler) isReconcilingFlows() bool {
3296 dh.mutexReconcilingFlowsFlag.RLock()
3297 value := dh.reconcilingFlows
3298 dh.mutexReconcilingFlowsFlag.RUnlock()
3299 return value
3300}