blob: 54e778b82345ff7468308edeefa9f75034284d92 [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 {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001471 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * 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 Hildebrandt366ef192021-05-05 11:07:44 +00001672 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring()
1673
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001674 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001675 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001676 }
1677 //MibDownload may run
1678 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1679 if pMibDlFsm != nil {
1680 _ = pMibDlFsm.Event(dlEvReset)
1681 }
1682 //port lock/unlock FSM's may be active
1683 if dh.pUnlockStateFsm != nil {
1684 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1685 }
1686 if dh.pLockStateFsm != nil {
1687 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1688 }
1689 //techProfile related PonAniConfigFsm FSM may be active
1690 if dh.pOnuTP != nil {
1691 // should always be the case here
1692 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1693 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001694 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001695 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001696 }
mpagenko900ee4b2020-10-12 11:56:34 +00001697 }
1698 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001699 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001700 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001701 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1702 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001703 dh.lockVlanConfig.RUnlock()
1704 //reset of all Fsm is always accompanied by global persistency data removal
1705 // no need to remove specific data
1706 pVlanFilterFsm.RequestClearPersistency(false)
1707 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001708 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001709 } else {
1710 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001711 }
1712 }
1713 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001714 if dh.getCollectorIsRunning() {
1715 // Stop collector routine
1716 dh.stopCollector <- true
1717 }
Himani Chawla1472c682021-03-17 17:11:14 +05301718 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301719 dh.stopAlarmManager <- true
1720 }
1721
mpagenko80622a52021-02-09 16:53:23 +00001722 //reset a possibly running upgrade FSM
1723 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1724 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1725 dh.lockUpgradeFsm.RLock()
1726 if dh.pOnuUpradeFsm != nil {
mpagenko59498c12021-03-18 14:15:15 +00001727 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1728 if pUpgradeStatemachine != nil {
1729 if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
1730 dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
1731 }
1732 _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
1733 }
1734 //else the FSM seems already to be in some released state
mpagenko80622a52021-02-09 16:53:23 +00001735 }
1736 dh.lockUpgradeFsm.RUnlock()
1737
mpagenko7d6bb022021-03-11 15:07:55 +00001738 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001739 return nil
1740}
1741
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1743 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 +05301744
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001745 // store persistent data collected during MIB upload processing
1746 if err := dh.storePersistentData(ctx); err != nil {
1747 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1748 log.Fields{"device-id": dh.deviceID, "err": err})
1749 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001750 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001751 dh.addAllUniPorts(ctx)
1752
mpagenkoa40e99a2020-11-17 13:50:39 +00001753 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1754 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1755 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1756 * disable/enable toggling here to allow traffic
1757 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1758 * like the py comment says:
1759 * # start by locking all the unis till mib sync and initial mib is downloaded
1760 * # this way we can capture the port down/up events when we are ready
1761 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301762
mpagenkoa40e99a2020-11-17 13:50:39 +00001763 // Init Uni Ports to Admin locked state
1764 // *** should generate UniLockStateDone event *****
1765 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001767 } else { //LockStateFSM already init
1768 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001770 }
1771}
1772
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1774 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301775 /* Mib download procedure -
1776 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1777 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001779 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001780 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001781 return
1782 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301783 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1784 if pMibDlFsm != nil {
1785 if pMibDlFsm.Is(dlStDisabled) {
1786 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 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 +05301788 // maybe try a FSM reset and then again ... - TODO!!!
1789 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301791 // maybe use more specific states here for the specific download steps ...
1792 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301794 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301796 //Begin MIB data download (running autonomously)
1797 }
1798 }
1799 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001801 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301802 // maybe try a FSM reset and then again ... - TODO!!!
1803 }
1804 /***** Mib download started */
1805 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301807 }
1808}
1809
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1811 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301812 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001813 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001815 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001816 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1817 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1818 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1819 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301821 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1822 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301824 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301826 }
1827 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301829 log.Fields{"device-id": dh.deviceID})
1830 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001831 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001832
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07001833 if !dh.getCollectorIsRunning() {
1834 // Start PM collector routine
1835 go dh.startCollector(ctx)
1836 }
1837 if !dh.getAlarmManagerIsRunning(ctx) {
1838 go dh.startAlarmManager(ctx)
1839 }
1840
Girish Gowdrae0140f02021-02-02 16:55:09 -08001841 // Initialize classical L2 PM Interval Counters
1842 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1843 // There is no way we should be landing here, but if we do then
1844 // there is nothing much we can do about this other than log error
1845 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1846 }
1847
mpagenkofc4f56e2020-11-04 17:17:49 +00001848 dh.ReadyForSpecificOmciConfig = true
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001849
1850 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1851 if pDevEntry == nil {
1852 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1853 return
1854 }
1855 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
1856 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1857 log.Fields{"device-id": dh.deviceID})
1858 go dh.reconcileDeviceTechProf(ctx)
1859 // reconcilement will be continued after ani config is done
1860 } else {
1861 // *** should generate UniUnlockStateDone event *****
1862 if dh.pUnlockStateFsm == nil {
1863 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1864 } else { //UnlockStateFSM already init
1865 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1866 dh.runUniLockFsm(ctx, false)
1867 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301868 }
1869}
1870
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1872 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301873
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001874 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301876 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1878 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001879 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001881 return
1882 }
1883 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 if err := dh.storePersistentData(ctx); err != nil {
1885 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001886 log.Fields{"device-id": dh.deviceID, "err": err})
1887 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301888 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 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 +05301890 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001892 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301893 }
1894}
1895
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1897 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001898 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001900 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1901 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001903 }
1904
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001906 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001908
1909 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001911
dbainbri4d3a0dc2020-12-02 00:33:42 +00001912 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001913 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001915 return
1916 }
1917 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918 if err := dh.storePersistentData(ctx); err != nil {
1919 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001920 log.Fields{"device-id": dh.deviceID, "err": err})
1921 }
mpagenko900ee4b2020-10-12 11:56:34 +00001922}
1923
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1925 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001926 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001928 voltha.OperStatus_ACTIVE); err != nil {
1929 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001931 }
1932
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001934 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001935 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001937
1938 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001940
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001942 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001944 return
1945 }
1946 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001947 if err := dh.storePersistentData(ctx); err != nil {
1948 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001949 log.Fields{"device-id": dh.deviceID, "err": err})
1950 }
mpagenko900ee4b2020-10-12 11:56:34 +00001951}
1952
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001954 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001956 // attention: the device reason update is done based on ONU-UNI-Port related activity
1957 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001958 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001959 // 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 +00001960 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301961 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001962 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001964 }
1965 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001967 // attention: the device reason update is done based on ONU-UNI-Port related activity
1968 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001969 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001970 // 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 +00001971 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001972 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001973 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301974}
1975
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1977 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001978 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301979 // attention: the device reason update is done based on ONU-UNI-Port related activity
1980 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301981
mpagenkof1fc3862021-02-16 10:09:52 +00001982 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001983 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001984 // which may be the case from some previous actvity on another UNI Port of the ONU
1985 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001986 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1987 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001988 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001989 }
1990 }
1991 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001992 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001993 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001995 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301996 }
mpagenkof1fc3862021-02-16 10:09:52 +00001997
1998 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1999 //events that request KvStore write
2000 if err := dh.storePersistentData(ctx); err != nil {
2001 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2002 log.Fields{"device-id": dh.deviceID, "err": err})
2003 }
2004 } else {
2005 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2006 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002007 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302008}
2009
Himani Chawla6d2ae152020-09-02 13:11:20 +05302010//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302012 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002013 case MibDatabaseSync:
2014 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002016 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002017 case UniLockStateDone:
2018 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002020 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002021 case MibDownloadDone:
2022 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002024 }
2025 case UniUnlockStateDone:
2026 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002028 }
mpagenko900ee4b2020-10-12 11:56:34 +00002029 case UniEnableStateDone:
2030 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002032 }
2033 case UniDisableStateDone:
2034 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002036 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002037 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002038 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002040 }
mpagenkof1fc3862021-02-16 10:09:52 +00002041 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002042 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002044 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002045 default:
2046 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002048 }
2049 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002050}
2051
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002053 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302055 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002056 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002058 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302059 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002061 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002063 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002064 //store UniPort with the System-PortNumber key
2065 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002066 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002067 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2069 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002070 } //error logging already within UniPort method
2071 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002073 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002074 }
2075 }
2076}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002077
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002078func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2079 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2080 if pDevEntry == nil {
2081 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2082 return
2083 }
2084 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2085 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2086 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2087 for _, mgmtEntityID := range pptpInstKeys {
2088 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2089 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2090 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2091 i++
2092 }
2093 } else {
2094 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2095 }
2096 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2097 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2098 for _, mgmtEntityID := range veipInstKeys {
2099 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2100 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2101 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2102 i++
2103 }
2104 } else {
2105 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2106 }
2107 if i == 0 {
2108 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2109 }
2110}
2111
mpagenko3af1f032020-06-10 08:53:41 +00002112// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002114 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302115 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002116 // with following remark:
2117 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2118 // # load on the core
2119
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002120 // 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 +00002121
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002122 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002123 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302124 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002125 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302126 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002127 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002128 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 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 +00002130 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002131 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002132 }
mpagenko3af1f032020-06-10 08:53:41 +00002133 }
2134 }
2135}
2136
2137// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002139 // compare enableUniPortStateUpdate() above
2140 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2141 for uniNo, uniPort := range dh.uniEntityMap {
2142 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302143 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002144 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302145 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002146 if !dh.isReconciling() {
2147 //maybe also use getter functions on uniPort - perhaps later ...
2148 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2149 } else {
2150 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2151 }
2152
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002153 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002154 }
2155}
2156
2157// ONU_Active/Inactive announcement on system KAFKA bus
2158// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002160 var de voltha.DeviceEvent
2161 eventContext := make(map[string]string)
2162 //Populating event context
2163 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002165 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302167 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002168 }
2169 oltSerialNumber := parentDevice.SerialNumber
2170
2171 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2172 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2173 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302174 eventContext["olt-serial-number"] = oltSerialNumber
2175 eventContext["device-id"] = aDeviceID
2176 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002178 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002179
2180 /* Populating device event body */
2181 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302182 de.ResourceId = aDeviceID
2183 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002184 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2185 de.Description = fmt.Sprintf("%s Event - %s - %s",
2186 cEventObjectType, cOnuActivatedEvent, "Raised")
2187 } else {
2188 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2189 de.Description = fmt.Sprintf("%s Event - %s - %s",
2190 cEventObjectType, cOnuActivatedEvent, "Cleared")
2191 }
2192 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2194 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302195 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002196 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302198 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002199}
2200
Himani Chawla4d908332020-08-31 12:30:20 +05302201// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002203 chLSFsm := make(chan Message, 2048)
2204 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302205 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002207 sFsmName = "LockStateFSM"
2208 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002210 sFsmName = "UnLockStateFSM"
2211 }
mpagenko3af1f032020-06-10 08:53:41 +00002212
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002214 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002216 return
2217 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002219 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002220 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302221 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002222 dh.pLockStateFsm = pLSFsm
2223 } else {
2224 dh.pUnlockStateFsm = pLSFsm
2225 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002227 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002229 }
2230}
2231
2232// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002233func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002234 /* Uni Port lock/unlock procedure -
2235 ***** should run via 'adminDone' state and generate the argument requested event *****
2236 */
2237 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302238 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002239 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2240 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2241 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002242 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302243 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002244 }
2245 } else {
2246 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2247 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2248 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002249 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302250 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002251 }
2252 }
2253 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002254 if pLSStatemachine.Is(uniStDisabled) {
2255 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002257 // maybe try a FSM reset and then again ... - TODO!!!
2258 } else {
2259 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002261 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002262 }
2263 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002265 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002266 // maybe try a FSM reset and then again ... - TODO!!!
2267 }
2268 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002270 // maybe try a FSM reset and then again ... - TODO!!!
2271 }
2272}
2273
mpagenko80622a52021-02-09 16:53:23 +00002274// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002275func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002276 //in here lockUpgradeFsm is already locked
2277 chUpgradeFsm := make(chan Message, 2048)
2278 var sFsmName = "OnuSwUpgradeFSM"
2279 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002280 if apDevEntry.PDevOmciCC == nil {
2281 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2282 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002283 }
mpagenko15ff4a52021-03-02 10:09:20 +00002284 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002285 sFsmName, chUpgradeFsm)
2286 if dh.pOnuUpradeFsm != nil {
2287 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2288 if pUpgradeStatemachine != nil {
2289 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2290 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2291 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2292 // maybe try a FSM reset and then again ... - TODO!!!
2293 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2294 }
2295 /***** LockStateFSM started */
2296 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2297 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2298 } else {
2299 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2300 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2301 // maybe try a FSM reset and then again ... - TODO!!!
2302 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2303 }
2304 } else {
2305 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2306 // maybe try a FSM reset and then again ... - TODO!!!
2307 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2308 }
2309 } else {
2310 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2311 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2312 }
2313 return nil
2314}
2315
2316// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2317func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2318 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2319 "device-id": dh.deviceID})
2320 dh.lockUpgradeFsm.Lock()
2321 defer dh.lockUpgradeFsm.Unlock()
2322 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2323}
2324
mpagenko15ff4a52021-03-02 10:09:20 +00002325// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2326func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2327 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2328 if pDevEntry == nil {
2329 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2330 return
2331 }
2332
2333 dh.lockUpgradeFsm.RLock()
2334 defer dh.lockUpgradeFsm.RUnlock()
2335 if dh.pOnuUpradeFsm != nil {
2336 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2337 if pUpgradeStatemachine != nil {
2338 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2339 // (some manual forced commit could do without)
2340 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002341 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002342 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2343 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2344 return
2345 }
2346 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2347 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2348 } else {
2349 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2350 log.Fields{"device-id": dh.deviceID})
2351 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2352 return
2353 }
2354 }
2355 }
2356 } else {
2357 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2358 }
2359}
2360
Himani Chawla6d2ae152020-09-02 13:11:20 +05302361//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002363
2364 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002365 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002366 kvbackend := &db.Backend{
2367 Client: dh.pOpenOnuAc.kvClient,
2368 StoreType: dh.pOpenOnuAc.KVStoreType,
2369 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002370 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002371 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2372 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002373
mpagenkoaf801632020-07-03 10:00:42 +00002374 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002375}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002376func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002378
mpagenkodff5dda2020-08-28 11:52:01 +00002379 for _, field := range flow.GetOfbFields(apFlowItem) {
2380 switch field.Type {
2381 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2382 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002384 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2385 }
mpagenko01e726e2020-10-23 09:45:29 +00002386 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002387 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2388 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302389 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002390 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302391 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2392 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002393 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2394 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002395 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2396 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302397 return
mpagenkodff5dda2020-08-28 11:52:01 +00002398 }
2399 }
mpagenko01e726e2020-10-23 09:45:29 +00002400 */
mpagenkodff5dda2020-08-28 11:52:01 +00002401 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2402 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302403 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002404 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302405 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002406 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302407 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002408 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002409 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302410 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002411 }
2412 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2413 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302414 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002416 "PCP": loAddPcp})
2417 }
2418 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2419 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002420 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002421 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2422 }
2423 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2424 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002425 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002426 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2427 }
2428 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2429 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002431 "IPv4-DST": field.GetIpv4Dst()})
2432 }
2433 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2434 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002436 "IPv4-SRC": field.GetIpv4Src()})
2437 }
2438 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2439 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002441 "Metadata": field.GetTableMetadata()})
2442 }
2443 /*
2444 default:
2445 {
2446 //all other entires ignored
2447 }
2448 */
2449 }
2450 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302451}
mpagenkodff5dda2020-08-28 11:52:01 +00002452
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002454 for _, action := range flow.GetActions(apFlowItem) {
2455 switch action.Type {
2456 /* not used:
2457 case of.OfpActionType_OFPAT_OUTPUT:
2458 {
mpagenko01e726e2020-10-23 09:45:29 +00002459 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002460 "Output": action.GetOutput()})
2461 }
2462 */
2463 case of.OfpActionType_OFPAT_PUSH_VLAN:
2464 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002466 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2467 }
2468 case of.OfpActionType_OFPAT_SET_FIELD:
2469 {
2470 pActionSetField := action.GetSetField()
2471 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002472 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002473 "OxcmClass": pActionSetField.Field.OxmClass})
2474 }
2475 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302476 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302478 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002479 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302480 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302482 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002483 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002484 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002485 "Type": pActionSetField.Field.GetOfbField().Type})
2486 }
2487 }
2488 /*
2489 default:
2490 {
2491 //all other entires ignored
2492 }
2493 */
2494 }
2495 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302496}
2497
2498//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302500 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2501 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2502 var loAddPcp, loSetPcp uint8
2503 var loIPProto uint32
2504 /* the TechProfileId is part of the flow Metadata - compare also comment within
2505 * OLT-Adapter:openolt_flowmgr.go
2506 * Metadata 8 bytes:
2507 * Most Significant 2 Bytes = Inner VLAN
2508 * Next 2 Bytes = Tech Profile ID(TPID)
2509 * Least Significant 4 Bytes = Port ID
2510 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2511 * subscriber related flows.
2512 */
2513
dbainbri4d3a0dc2020-12-02 00:33:42 +00002514 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302515 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002516 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302517 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002518 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302519 }
mpagenko551a4d42020-12-08 18:09:20 +00002520 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002521 loCookie := apFlowItem.GetCookie()
2522 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002524 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302525
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002527 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302528 if loIPProto == 2 {
2529 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2530 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002531 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2532 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302533 return nil
2534 }
mpagenko01e726e2020-10-23 09:45:29 +00002535 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002537
2538 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002540 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2541 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2542 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2543 //TODO!!: Use DeviceId within the error response to rwCore
2544 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002545 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002546 }
2547 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002548 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002549 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2550 } else {
2551 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2552 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2553 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302554 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002555 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002556 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002557 }
mpagenko9a304ea2020-12-16 15:54:01 +00002558
2559 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002560 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002561 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302562 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002563 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002564 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002565 dh.lockVlanConfig.RUnlock()
2566 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002567 }
mpagenkof1fc3862021-02-16 10:09:52 +00002568 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002570 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002571}
2572
2573//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002574func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002575 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2576 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2577 //no extra check is done on the rule parameters
2578 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2579 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2580 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2581 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002582 // - 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 +00002583 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002584 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002585
2586 /* TT related temporary workaround - should not be needed anymore
2587 for _, field := range flow.GetOfbFields(apFlowItem) {
2588 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2589 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002590 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002591 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2592 if loIPProto == 2 {
2593 // 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 +00002594 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002595 log.Fields{"device-id": dh.deviceID})
2596 return nil
2597 }
2598 }
2599 } //for all OfbFields
2600 */
2601
mpagenko9a304ea2020-12-16 15:54:01 +00002602 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002603 dh.lockVlanConfig.RLock()
2604 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002605 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002607 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002609 log.Fields{"device-id": dh.deviceID})
2610 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002611 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002613
mpagenko01e726e2020-10-23 09:45:29 +00002614 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002615}
2616
Himani Chawla26e555c2020-08-31 12:30:20 +05302617// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002618// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002619func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002620 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002621 chVlanFilterFsm := make(chan Message, 2048)
2622
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002624 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002625 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302626 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002627 }
2628
dbainbri4d3a0dc2020-12-02 00:33:42 +00002629 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002630 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2631 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002632 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002633 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002634 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2635 // (from parallel processing)
2636 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302637 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002638 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2639 if pVlanFilterStatemachine != nil {
2640 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2641 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002642 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302643 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002644 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302645 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302647 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2648 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002651 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302652 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002653 }
2654 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002655 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002656 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302657 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002658 }
2659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002660 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002661 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302662 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002663 }
2664 return nil
2665}
2666
mpagenkofc4f56e2020-11-04 17:17:49 +00002667//VerifyVlanConfigRequest checks on existence of a given uniPort
2668// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002669func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002670 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2671 var pCurrentUniPort *onuUniPort
2672 for _, uniPort := range dh.uniEntityMap {
2673 // only if this port is validated for operState transfer
2674 if uniPort.uniID == uint8(aUniID) {
2675 pCurrentUniPort = uniPort
2676 break //found - end search loop
2677 }
2678 }
2679 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002680 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002681 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2682 return
2683 }
mpagenko551a4d42020-12-08 18:09:20 +00002684 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002685}
2686
mpagenkodff5dda2020-08-28 11:52:01 +00002687//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002688func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002689 //TODO!! verify and start pending flow configuration
2690 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2691 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002692
2693 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302694 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002695 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002696 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2697 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2698 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002699 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2700 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2701 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2702 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2703 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2704 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2705 } else {
2706 /***** UniVlanConfigFsm continued */
2707 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2708 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2709 "UniPort": apUniPort.portNo})
2710 }
2711 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2712 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2713 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2714 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2715 } else {
2716 /***** UniVlanConfigFsm continued */
2717 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2718 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2719 "UniPort": apUniPort.portNo})
2720 }
mpagenkodff5dda2020-08-28 11:52:01 +00002721 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002722 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2723 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002724 "UniPort": apUniPort.portNo})
2725 }
2726 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002727 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2728 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2729 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002730 }
2731 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002732 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002733 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002734 }
mpagenkof1fc3862021-02-16 10:09:52 +00002735 } else {
2736 dh.lockVlanConfig.RUnlock()
2737 }
mpagenkodff5dda2020-08-28 11:52:01 +00002738}
2739
2740//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2741// 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 +00002742func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2743 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002744 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2745 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002746 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302747 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002748 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002749}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002750
mpagenkof1fc3862021-02-16 10:09:52 +00002751//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2752func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2753 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2754 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2755 // obviously then parallel processing on the cancel must be avoided
2756 // deadline context to ensure completion of background routines waited for
2757 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2758 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2759 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2760
2761 aPDevEntry.resetKvProcessingErrorIndication()
2762 var wg sync.WaitGroup
2763 wg.Add(1) // for the 1 go routine to finish
2764
2765 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2766 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2767
2768 return aPDevEntry.getKvProcessingErrorIndication()
2769}
2770
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002771//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2772//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002773func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2774 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002775
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002776 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002777 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002778 return nil
2779 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002780 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002781
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002783 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002784 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002785 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2786 }
2787 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2788
mpagenkof1fc3862021-02-16 10:09:52 +00002789 if aWriteToKvStore {
2790 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2791 }
2792 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002793}
2794
dbainbri4d3a0dc2020-12-02 00:33:42 +00002795func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002796 defer cancel() //ensure termination of context (may be pro forma)
2797 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002798 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002799 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002800}
2801
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002803
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002804 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002805 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002806 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2808 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002809 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002810 return err
2811 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002812 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002813 return nil
2814 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002815 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002816 return nil
2817}
2818
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2820 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002821 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002823 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2824 }
mpagenkof1fc3862021-02-16 10:09:52 +00002825 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002826}
2827
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002828func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2829 var errStr string = ""
2830 for _, err := range errS {
2831 if err != nil {
2832 errStr = errStr + err.Error() + " "
2833 }
2834 }
2835 if errStr != "" {
2836 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2837 }
2838 return nil
2839}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002840
2841// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2842func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2843 dh.lockDevice.RLock()
2844 defer dh.lockDevice.RUnlock()
2845 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2846 return uniPort.entityID, nil
2847 }
2848 return 0, errors.New("error-fetching-uni-port")
2849}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002850
2851// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002852func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2853 var errorsList []error
2854 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 -08002855
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002856 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2857 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2858 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2859
2860 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2861 // successfully.
2862 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2863 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2864 if len(errorsList) > 0 {
2865 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2866 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002867 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002868 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2869 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002870}
2871
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002872func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2873 var err error
2874 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002875 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002876
2877 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2878 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2879 errorsList = append(errorsList, err)
2880 }
2881 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002882 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002883
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002884 return errorsList
2885}
2886
2887func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2888 var err error
2889 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002890 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002891 // Check if group metric related config is updated
2892 for _, v := range pmConfigs.Groups {
2893 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2894 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2895 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2896
2897 if ok && m.frequency != v.GroupFreq {
2898 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2899 errorsList = append(errorsList, err)
2900 }
2901 }
2902 if ok && m.enabled != v.Enabled {
2903 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2904 errorsList = append(errorsList, err)
2905 }
2906 }
2907 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002908 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002909 return errorsList
2910}
2911
2912func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2913 var err error
2914 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002915 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002916 // Check if standalone metric related config is updated
2917 for _, v := range pmConfigs.Metrics {
2918 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002919 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002920 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2921
2922 if ok && m.frequency != v.SampleFreq {
2923 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2924 errorsList = append(errorsList, err)
2925 }
2926 }
2927 if ok && m.enabled != v.Enabled {
2928 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2929 errorsList = append(errorsList, err)
2930 }
2931 }
2932 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002933 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002934 return errorsList
2935}
2936
2937// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002938func (dh *deviceHandler) startCollector(ctx context.Context) {
2939 logger.Debugf(ctx, "startingCollector")
2940
2941 // Start routine to process OMCI GET Responses
2942 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002943 // Initialize the next metric collection time.
2944 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2945 // reset like onu rebooted.
2946 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002947 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002948 for {
2949 select {
2950 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002951 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002952 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002953 // Stop the L2 PM FSM
2954 go func() {
2955 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2956 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2957 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2958 }
2959 } else {
2960 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2961 }
2962 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002963 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2964 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2965 }
2966 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2967 dh.pOnuMetricsMgr.stopTicks <- true
2968 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002969
Girish Gowdrae09a6202021-01-12 18:10:59 -08002970 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002971 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2972 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2973 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2974 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2975 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002976 // Update the next metric collection time.
2977 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002978 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002979 } else {
2980 if dh.pmConfigs.Grouped { // metrics are managed as a group
2981 // parse through the group and standalone metrics to see it is time to collect their metrics
2982 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002983
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002984 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2985 // 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 -08002986 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2987 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002988 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2989 }
2990 }
2991 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2992 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2993 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2994 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2995 }
2996 }
2997 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2998
2999 // parse through the group and update the next metric collection time
3000 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3001 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3002 // 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 -08003003 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3004 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003005 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3006 }
3007 }
3008 // parse through the standalone metrics and update the next metric collection time
3009 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3010 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3011 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3012 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3013 }
3014 }
3015 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3016 } /* else { // metrics are not managed as a group
3017 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3018 } */
3019 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003020 }
3021 }
3022}
kesavandfdf77632021-01-26 23:40:33 -05003023
3024func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3025
3026 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3027 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3028}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003029
mpagenkof1fc3862021-02-16 10:09:52 +00003030func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3031 if pFsm == nil {
3032 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003033 }
mpagenkof1fc3862021-02-16 10:09:52 +00003034 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003035}
3036
mpagenkof1fc3862021-02-16 10:09:52 +00003037func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3038 var pFsm *fsm.FSM
3039 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3040 switch omciFsm {
3041 case cUploadFsm:
3042 {
3043 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3044 }
3045 case cDownloadFsm:
3046 {
3047 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3048 }
3049 case cUniLockFsm:
3050 {
3051 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3052 }
3053 case cUniUnLockFsm:
3054 {
3055 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3056 }
3057 case cL2PmFsm:
3058 {
3059 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3060 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3061 } else {
3062 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003063 }
3064 }
mpagenko80622a52021-02-09 16:53:23 +00003065 case cOnuUpgradeFsm:
3066 {
3067 dh.lockUpgradeFsm.RLock()
3068 defer dh.lockUpgradeFsm.RUnlock()
3069 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3070 }
mpagenkof1fc3862021-02-16 10:09:52 +00003071 default:
3072 {
3073 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3074 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3075 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003076 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003077 }
mpagenkof1fc3862021-02-16 10:09:52 +00003078 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003079}
3080
mpagenkof1fc3862021-02-16 10:09:52 +00003081func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3082 for _, v := range dh.pOnuTP.pAniConfigFsm {
3083 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003084 return false
3085 }
3086 }
3087 return true
3088}
3089
mpagenkof1fc3862021-02-16 10:09:52 +00003090func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3091 dh.lockVlanConfig.RLock()
3092 defer dh.lockVlanConfig.RUnlock()
3093 for _, v := range dh.UniVlanConfigFsmMap {
3094 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3095 return false
3096 }
3097 }
3098 return true //FSM not active - so there is no activity on omci
3099}
3100
3101func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3102 dh.lockVlanConfig.RLock()
3103 defer dh.lockVlanConfig.RUnlock()
3104 for _, v := range dh.UniVlanConfigFsmMap {
3105 if v.pAdaptFsm.pFsm != nil {
3106 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3107 return true //there is at least one VLAN FSM with some active configuration
3108 }
3109 }
3110 }
3111 return false //there is no VLAN FSM with some active configuration
3112}
3113
3114func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3115 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3116 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3117 return false
3118 }
3119 }
3120 // a further check is done to identify, if at least some data traffic related configuration exists
3121 // 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])
3122 return dh.checkUserServiceExists(ctx)
3123}
3124
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003125func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3126 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3127 if err := dh.resetFsms(ctx, false); err != nil {
3128 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3129 // TODO: fatal error reset ONU, delete deviceHandler!
3130 return
3131 }
3132 if !dh.getCollectorIsRunning() {
3133 // Start PM collector routine
3134 go dh.startCollector(ctx)
3135 }
Himani Chawla1472c682021-03-17 17:11:14 +05303136 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303137 go dh.startAlarmManager(ctx)
3138 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003139 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003140 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003141}
3142
3143func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3144 dh.mutexCollectorFlag.Lock()
3145 dh.collectorIsRunning = flagValue
3146 dh.mutexCollectorFlag.Unlock()
3147}
3148
3149func (dh *deviceHandler) getCollectorIsRunning() bool {
3150 dh.mutexCollectorFlag.RLock()
3151 flagValue := dh.collectorIsRunning
3152 dh.mutexCollectorFlag.RUnlock()
3153 return flagValue
3154}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303155
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303156func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3157 dh.mutextAlarmManagerFlag.Lock()
3158 dh.alarmManagerIsRunning = flagValue
3159 dh.mutextAlarmManagerFlag.Unlock()
3160}
3161
Himani Chawla1472c682021-03-17 17:11:14 +05303162func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303163 dh.mutextAlarmManagerFlag.RLock()
3164 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303165 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303166 dh.mutextAlarmManagerFlag.RUnlock()
3167 return flagValue
3168}
3169
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303170func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3171 logger.Debugf(ctx, "startingAlarmManager")
3172
3173 // Start routine to process OMCI GET Responses
3174 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303175 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303176 if stop := <-dh.stopAlarmManager; stop {
3177 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303178 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303179 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303180 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3181 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3182 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303183 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303184 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303185 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3186 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303187 }
3188}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003189
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003190func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003191 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003192
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003193 if !dh.isReconciling() {
3194 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003195 logger.Debugw(ctx, "wait for channel signal or timeout",
3196 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003197 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003198 case success := <-dh.chReconcilingFinished:
3199 if success {
3200 logger.Debugw(ctx, "reconciling has been finished in time",
3201 log.Fields{"device-id": dh.deviceID})
3202 } else {
3203 logger.Debugw(ctx, "wait for reconciling aborted",
3204 log.Fields{"device-id": dh.deviceID})
3205 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003206 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003207 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3208 log.Fields{"device-id": dh.deviceID})
3209 }
3210 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003211 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003212 dh.mutexReconcilingFlag.Unlock()
3213 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003214 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003215 dh.mutexReconcilingFlag.Lock()
3216 if skipOnuConfig {
3217 dh.reconciling = cSkipOnuConfigReconciling
3218 } else {
3219 dh.reconciling = cOnuConfigReconciling
3220 }
3221 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003222}
3223
3224func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3225 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3226 if dh.isReconciling() {
3227 dh.chReconcilingFinished <- true
3228 } else {
3229 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3230 }
3231}
3232
3233func (dh *deviceHandler) isReconciling() bool {
3234 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003235 defer dh.mutexReconcilingFlag.RUnlock()
3236 return dh.reconciling != cNoReconciling
3237}
3238
3239func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3240 dh.mutexReconcilingFlag.RLock()
3241 defer dh.mutexReconcilingFlag.RUnlock()
3242 return dh.reconciling == cSkipOnuConfigReconciling
3243}
3244
3245func (dh *deviceHandler) setDeviceReason(value uint8) {
3246 dh.mutexDeviceReason.Lock()
3247 dh.deviceReason = value
3248 dh.mutexDeviceReason.Unlock()
3249}
3250
3251func (dh *deviceHandler) getDeviceReason() uint8 {
3252 dh.mutexDeviceReason.RLock()
3253 value := dh.deviceReason
3254 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003255 return value
3256}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003257
3258func (dh *deviceHandler) getDeviceReasonString() string {
3259 return deviceReasonMap[dh.getDeviceReason()]
3260}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003261
3262func (dh *deviceHandler) setReconcilingFlows(value bool) {
3263 dh.mutexReconcilingFlowsFlag.Lock()
3264 dh.reconcilingFlows = value
3265 dh.mutexReconcilingFlowsFlag.Unlock()
3266}
3267
3268func (dh *deviceHandler) isReconcilingFlows() bool {
3269 dh.mutexReconcilingFlowsFlag.RLock()
3270 value := dh.reconcilingFlows
3271 dh.mutexReconcilingFlowsFlag.RUnlock()
3272 return value
3273}