blob: 817a14719cd397ded54d1b37e6bc2dd4eec14395 [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
219 ReadyForSpecificOmciConfig bool
220 deletionInProgress bool
221 mutexDeletionInProgressFlag sync.RWMutex
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222}
223
Himani Chawla6d2ae152020-09-02 13:11:20 +0530224//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530225func 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 +0530226 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227 dh.coreProxy = cp
228 dh.AdapterProxy = ap
229 dh.EventProxy = ep
230 cloned := (proto.Clone(device)).(*voltha.Device)
231 dh.deviceID = cloned.Id
232 dh.DeviceType = cloned.Type
233 dh.adminState = "up"
234 dh.device = cloned
235 dh.pOpenOnuAc = adapter
236 dh.exitChannel = make(chan int, 1)
237 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000238 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000239 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530241 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530242 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.stopHeartbeatCheck = make(chan bool, 2)
244 //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 +0000245 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530246 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000247 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000248 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000249 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000250 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000251 dh.chReconcilingFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000252 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000253 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800255 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
256 dh.pmConfigs = cloned.PmConfigs
257 } /* else {
258 // will be populated when onu_metrics_mananger is initialized.
259 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800260
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 // Device related state machine
262 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000263 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000264 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000265 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
266 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
267 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
268 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
269 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 },
271 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000272 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
273 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
274 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
275 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
276 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
277 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
278 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
279 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280 },
281 )
mpagenkoaf801632020-07-03 10:00:42 +0000282
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283 return &dh
284}
285
Himani Chawla6d2ae152020-09-02 13:11:20 +0530286// start save the device to the data model
287func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000288 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291}
292
Himani Chawla4d908332020-08-31 12:30:20 +0530293/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000294// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530295func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 logger.Debug("stopping-device-handler")
297 dh.exitChannel <- 1
298}
Himani Chawla4d908332020-08-31 12:30:20 +0530299*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300
301// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530302// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000303
Girish Gowdrae0140f02021-02-02 16:55:09 -0800304//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530305func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000309 if dh.pDeviceStateFsm.Is(devStNull) {
310 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
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())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800314 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
315 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800316 // Now, set the initial PM configuration for that device
317 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
318 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
319 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800320 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323 }
324
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325}
326
mpagenko057889c2021-01-21 16:51:58 +0000327func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530328 msgBody := msg.GetBody()
329 omciMsg := &ic.InterAdapterOmciMessage{}
330 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530332 "device-id": dh.deviceID, "error": err})
333 return err
334 }
335
mpagenko80622a52021-02-09 16:53:23 +0000336 /* 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 +0530337 //assuming omci message content is hex coded!
338 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000341 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000342 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530343 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000344 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000346 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 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 +0530348 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000350 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530351}
352
Himani Chawla6d2ae152020-09-02 13:11:20 +0530353func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000356
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000358
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000360 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000362 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
363 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530364 if dh.pOnuTP == nil {
365 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530369 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000370 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000372 "device-state": dh.getDeviceReasonString()})
373 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000375 //previous state test here was just this one, now extended for more states to reject the SetRequest:
376 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
377 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530378
379 msgBody := msg.GetBody()
380 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
381 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530383 "device-id": dh.deviceID, "error": err})
384 return err
385 }
386
387 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
389 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000391 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392
393 if techProfMsg.UniId > 255 {
394 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
395 techProfMsg.UniId, dh.deviceID))
396 }
397 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800398 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
399 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000400 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800401 return err
402 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403
dbainbri4d3a0dc2020-12-02 00:33:42 +0000404 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 // if there has been some change for some uni TechProfilePath
406 //in order to allow concurrent calls to other dh instances we do not wait for execution here
407 //but doing so we can not indicate problems to the caller (who does what with that then?)
408 //by now we just assume straightforward successful execution
409 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
410 // possible problems to the caller later autonomously
411
412 // deadline context to ensure completion of background routines waited for
413 //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 +0530414 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 dctx, cancel := context.WithDeadline(context.Background(), deadline)
416
Girish Gowdra041dcb32020-11-16 16:54:30 -0800417 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418 pDevEntry.resetKvProcessingErrorIndication()
419
Himani Chawla26e555c2020-08-31 12:30:20 +0530420 var wg sync.WaitGroup
421 wg.Add(2) // for the 2 go routines to finish
422 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000423 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
424 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
425 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426
Girish Gowdra041dcb32020-11-16 16:54:30 -0800427 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530428 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000429 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530430 return nil
431}
432
Himani Chawla6d2ae152020-09-02 13:11:20 +0530433func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000434 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 msg *ic.InterAdapterMessage) error {
436
dbainbri4d3a0dc2020-12-02 00:33:42 +0000437 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000438
dbainbri4d3a0dc2020-12-02 00:33:42 +0000439 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000441 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
443 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530444 if dh.pOnuTP == nil {
445 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000446 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530447 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 }
450
451 msgBody := msg.GetBody()
452 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
453 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000454 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 "device-id": dh.deviceID, "error": err})
456 return err
457 }
458
459 //compare TECH_PROFILE_DOWNLOAD_REQUEST
460 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000461 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530462
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000463 if delGemPortMsg.UniId > 255 {
464 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
465 delGemPortMsg.UniId, dh.deviceID))
466 }
467 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800468 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
469 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 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 -0800471 return err
472 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530473
mpagenkofc4f56e2020-11-04 17:17:49 +0000474 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000475
mpagenkofc4f56e2020-11-04 17:17:49 +0000476 // deadline context to ensure completion of background routines waited for
477 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
478 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479
Girish Gowdra041dcb32020-11-16 16:54:30 -0800480 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481
mpagenkofc4f56e2020-11-04 17:17:49 +0000482 var wg sync.WaitGroup
483 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000485 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000487
Girish Gowdra041dcb32020-11-16 16:54:30 -0800488 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530489}
490
Himani Chawla6d2ae152020-09-02 13:11:20 +0530491func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000496
dbainbri4d3a0dc2020-12-02 00:33:42 +0000497 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
501 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 if dh.pOnuTP == nil {
503 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000504 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530505 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530507 }
508
509 msgBody := msg.GetBody()
510 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
511 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 "device-id": dh.deviceID, "error": err})
514 return err
515 }
516
517 //compare TECH_PROFILE_DOWNLOAD_REQUEST
518 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
521 if delTcontMsg.UniId > 255 {
522 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
523 delTcontMsg.UniId, dh.deviceID))
524 }
525 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800526 tpPath := delTcontMsg.TpPath
527 tpID, err := GetTpIDFromTpPath(tpPath)
528 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000529 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800530 return err
531 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530535 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530536 dctx, cancel := context.WithDeadline(context.Background(), deadline)
537
Girish Gowdra041dcb32020-11-16 16:54:30 -0800538 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 pDevEntry.resetKvProcessingErrorIndication()
540
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 var wg sync.WaitGroup
542 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000543 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 cResourceTcont, delTcontMsg.AllocId, &wg)
545 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000546 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
547 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000548
Girish Gowdra041dcb32020-11-16 16:54:30 -0800549 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530550 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530551 return nil
552}
553
Himani Chawla6d2ae152020-09-02 13:11:20 +0530554//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000555// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
556// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000557func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000558 msgID := msg.Header.Id
559 msgType := msg.Header.Type
560 fromTopic := msg.Header.FromTopic
561 toTopic := msg.Header.ToTopic
562 toDeviceID := msg.Header.ToDeviceId
563 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000565 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
566
567 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000568 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000569 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
570 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 {
mpagenko057889c2021-01-21 16:51:58 +0000572 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000573 }
mpagenkoaf801632020-07-03 10:00:42 +0000574 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
575 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000577 }
578 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
579 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000581
mpagenkoaf801632020-07-03 10:00:42 +0000582 }
583 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
584 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000585 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000586 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000587 default:
588 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000590 "msgType": msg.Header.Type, "device-id": dh.deviceID})
591 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000592 }
593 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000594}
595
mpagenkodff5dda2020-08-28 11:52:01 +0000596//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
598 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000599 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000600 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000601
mpagenko01e726e2020-10-23 09:45:29 +0000602 var retError error = nil
603 //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 +0000604 if apOfFlowChanges.ToRemove != nil {
605 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000606 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000608 "device-id": dh.deviceID})
609 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000610 continue
611 }
612 flowInPort := flow.GetInPort(flowItem)
613 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 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 +0000615 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
616 continue
617 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000618 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000619 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000621 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000622 continue
623 } else {
624 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530625 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000626 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
627 loUniPort = uniPort
628 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000630 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
631 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
632 flowInPort, dh.deviceID)
633 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000634 }
635 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000637 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000638 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000640 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000641 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000643 log.Fields{"device-id": dh.deviceID, "error": err})
644 retError = err
645 continue
646 //return err
647 } else { // if last setting succeeds, overwrite possibly previously set error
648 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000649 }
650 }
651 }
652 }
mpagenko01e726e2020-10-23 09:45:29 +0000653 if apOfFlowChanges.ToAdd != nil {
654 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
655 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000657 "device-id": dh.deviceID})
658 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
659 continue
660 }
661 flowInPort := flow.GetInPort(flowItem)
662 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663 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 +0000664 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
665 continue
666 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
667 } else if flowInPort == dh.ponPortNumber {
668 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000670 "device-id": dh.deviceID, "inPort": flowInPort})
671 continue
672 } else {
673 // this is the relevant upstream flow
674 var loUniPort *onuUniPort
675 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
676 loUniPort = uniPort
677 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000679 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
680 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
681 flowInPort, dh.deviceID)
682 continue
683 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
684 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000685 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
686 // if not, we just throw some error here to have an indication about that, if we really need to support that
687 // then we would need to create some means to activate the internal stored flows
688 // after the device gets active automatically (and still with its dependency to the TechProfile)
689 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
690 // also abort for the other still possible flows here
691 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000693 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000694 return fmt.Errorf("improper device state on device %s", dh.deviceID)
695 }
696
mpagenko01e726e2020-10-23 09:45:29 +0000697 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000699 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
700 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000702 //try next flow after processing error
703 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000705 log.Fields{"device-id": dh.deviceID, "error": err})
706 retError = err
707 continue
708 //return err
709 } else { // if last setting succeeds, overwrite possibly previously set error
710 retError = nil
711 }
712 }
713 }
714 }
715 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000716}
717
Himani Chawla6d2ae152020-09-02 13:11:20 +0530718//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000719//following are the expected device states after this activity:
720//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
721// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
723 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000724
mpagenko900ee4b2020-10-12 11:56:34 +0000725 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000726 //note that disableDevice sequences in some 'ONU active' state may yield also
727 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000728 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000729 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000730 //disable-device shall be just a UNi/ONU-G related admin state setting
731 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000732
mpagenkofc4f56e2020-11-04 17:17:49 +0000733 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000734 // disable UNI ports/ONU
735 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
736 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000738 } else { //LockStateFSM already init
739 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000741 }
742 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000744 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000746 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
747 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000748 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000749 }
mpagenko01e726e2020-10-23 09:45:29 +0000750 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000751
752 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000754 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300755 }
756}
757
Himani Chawla6d2ae152020-09-02 13:11:20 +0530758//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
760 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000761
mpagenkofc4f56e2020-11-04 17:17:49 +0000762 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
763 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
764 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
765 // for real ONU's that should have nearly no influence
766 // Note that for real ONU's there is anyway a problematic situation with following sequence:
767 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
768 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
769 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
770 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
771
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000772 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000773 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000774 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000776 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000777 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000779 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300780}
781
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
783 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000784
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000786 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000788 return
789 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000791 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000793 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000795 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000796 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000797 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000798 }
Himani Chawla4d908332020-08-31 12:30:20 +0530799 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000800 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
801 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
802 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
803 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000805}
806
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
808 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000809
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000811 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000813 if !dh.isSkipOnuConfigReconciling() {
814 dh.stopReconciling(ctx)
815 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 return
817 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000818 dh.pOnuTP.lockTpProcMutex()
819 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000820 pDevEntry.persUniConfigMutex.RLock()
821 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000822
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000823 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000825 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000826 if !dh.isSkipOnuConfigReconciling() {
827 dh.stopReconciling(ctx)
828 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000829 return
830 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000831 techProfsFound := false
832 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000833 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000834 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
835 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000836 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000837 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000838 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000839 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000840 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800841 for tpID := range uniData.PersTpPathMap {
842 // deadline context to ensure completion of background routines waited for
843 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
844 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000846
Girish Gowdra041dcb32020-11-16 16:54:30 -0800847 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
848 var wg sync.WaitGroup
849 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
851 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800852 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800854 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000856 if len(uniData.PersFlowParams) != 0 {
857 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000858 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000860 if !techProfsFound {
861 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
862 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000863 if !dh.isSkipOnuConfigReconciling() {
864 dh.stopReconciling(ctx)
865 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000866 return
867 }
868 if dh.isSkipOnuConfigReconciling() {
869 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
870 }
871 if !flowsFound {
872 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
873 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000874 if !dh.isSkipOnuConfigReconciling() {
875 dh.stopReconciling(ctx)
876 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000877 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878}
879
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
881 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000886 if !dh.isSkipOnuConfigReconciling() {
887 dh.stopReconciling(ctx)
888 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000889 return
890 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000891 pDevEntry.persUniConfigMutex.RLock()
892 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000893
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000894 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000896 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000897 if !dh.isSkipOnuConfigReconciling() {
898 dh.stopReconciling(ctx)
899 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 return
901 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000902 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000904 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
905 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000906 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000907 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 continue
909 }
910 if len(uniData.PersTpPathMap) == 0 {
911 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
912 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000913 // It doesn't make sense to configure any flows if no TPs are available
914 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000915 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000916 var uniPort *onuUniPort
917 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000919 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000920 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
921 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000922 if !dh.isSkipOnuConfigReconciling() {
923 dh.stopReconciling(ctx)
924 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000925 return
926 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000927 flowsFound = true
928 flowsProcessed := 0
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000929 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000930 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000931 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000932 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000933 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000934 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000935 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
936 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000938 }
mpagenkof1fc3862021-02-16 10:09:52 +0000939 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000940 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000941 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000943 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000944 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000946 }
947 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000948 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000949 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000950 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
951 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
952 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
953 }
954 if !flowsFound {
955 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
956 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000957 if !dh.isSkipOnuConfigReconciling() {
958 dh.stopReconciling(ctx)
959 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 return
961 }
962 if dh.isSkipOnuConfigReconciling() {
963 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000964 }
965}
966
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000967func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
968 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000969 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000970}
971
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
973 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000976 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000977 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000979 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000980 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000981
982 // deadline context to ensure completion of background routines waited for
983 //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 +0530984 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000985 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000986
987 pDevEntry.resetKvProcessingErrorIndication()
988
989 var wg sync.WaitGroup
990 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000991 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
992 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000993
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000994 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000995 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000996}
997
mpagenko15ff4a52021-03-02 10:09:20 +0000998//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
999// before this change here return like this was used:
1000// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1001//was and is called in background - error return does not make sense
1002func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1003 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1004 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001006 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001007 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301009 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001010 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001011 return
Himani Chawla4d908332020-08-31 12:30:20 +05301012 }
mpagenko01e726e2020-10-23 09:45:29 +00001013
1014 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001016
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001018 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001020 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001021 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001023 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001024 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001025 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001026 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001027 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001028 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +00001029 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1030 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1031 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1032 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001033}
1034
mpagenkoc8bba412021-01-15 15:38:44 +00001035//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001036func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1037 apDownloadManager *adapterDownloadManager) error {
1038 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001039 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001040
1041 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001042 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1043 if pDevEntry == nil {
1044 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1045 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1046 }
1047
mpagenko80622a52021-02-09 16:53:23 +00001048 if dh.ReadyForSpecificOmciConfig {
mpagenko15ff4a52021-03-02 10:09:20 +00001049 var inactiveImageID uint16
1050 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1051 dh.lockUpgradeFsm.Lock()
1052 defer dh.lockUpgradeFsm.Unlock()
1053 if dh.pOnuUpradeFsm == nil {
1054 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1055 if err == nil {
1056 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1057 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1058 "device-id": dh.deviceID, "error": err})
1059 }
1060 } else {
1061 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001062 "device-id": dh.deviceID, "error": err})
1063 }
mpagenko15ff4a52021-03-02 10:09:20 +00001064 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1065 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1066 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1067 if pUpgradeStatemachine != nil {
1068 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1069 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1070 "device-id": dh.deviceID, "error": err})
1071 }
1072 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1073 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1074 // for now a second start of download should work again
1075 } else { //should never occur
1076 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1077 "device-id": dh.deviceID})
1078 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001079 }
mpagenko80622a52021-02-09 16:53:23 +00001080 }
mpagenko15ff4a52021-03-02 10:09:20 +00001081 } else {
1082 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1083 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001084 }
1085 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001086 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1087 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001088 }
1089 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001090}
1091
Himani Chawla6d2ae152020-09-02 13:11:20 +05301092// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001093// #####################################################################################
1094
1095// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301096// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001097
dbainbri4d3a0dc2020-12-02 00:33:42 +00001098func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1099 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 +00001100}
1101
1102// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001104
dbainbri4d3a0dc2020-12-02 00:33:42 +00001105 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001106 var err error
1107
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108 // populate what we know. rest comes later after mib sync
1109 dh.device.Root = false
1110 dh.device.Vendor = "OpenONU"
1111 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001112 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001113 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001115 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001116
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001117 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1119 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301120 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001121 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001123 log.Fields{"device-id": dh.deviceID})
1124 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125
Himani Chawla4d908332020-08-31 12:30:20 +05301126 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001127 dh.ponPortNumber = dh.device.ParentPortNo
1128
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001129 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1130 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1131 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301134 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135
1136 /*
1137 self._pon = PonPort.create(self, self._pon_port_number)
1138 self._pon.add_peer(self.parent_id, self._pon_port_number)
1139 self.logger.debug('adding-pon-port-to-agent',
1140 type=self._pon.get_port().type,
1141 admin_state=self._pon.get_port().admin_state,
1142 oper_status=self._pon.get_port().oper_status,
1143 )
1144 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001145 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001147 var ponPortNo uint32 = 1
1148 if dh.ponPortNumber != 0 {
1149 ponPortNo = dh.ponPortNumber
1150 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001151
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001152 pPonPort := &voltha.Port{
1153 PortNo: ponPortNo,
1154 Label: fmt.Sprintf("pon-%d", ponPortNo),
1155 Type: voltha.Port_PON_ONU,
1156 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301157 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001158 PortNo: ponPortNo}}, // Peer port is parent's port number
1159 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001160 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1161 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001162 e.Cancel(err)
1163 return
1164 }
1165 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001166 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001167 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001169}
1170
1171// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001173
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001175 var err error
1176 /*
1177 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1178 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1179 return nil
1180 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001181 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1182 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183 e.Cancel(err)
1184 return
1185 }
1186
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001187 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001189 // reconcilement will be continued after mib download is done
1190 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001191
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001192 /*
1193 ############################################################################
1194 # Setup Alarm handler
1195 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1196 device.serial_number)
1197 ############################################################################
1198 # Setup PM configuration for this device
1199 # Pass in ONU specific options
1200 kwargs = {
1201 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1202 'heartbeat': self.heartbeat,
1203 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1204 }
1205 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1206 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1207 self.logical_device_id, device.serial_number,
1208 grouped=True, freq_override=False, **kwargs)
1209 pm_config = self._pm_metrics.make_proto()
1210 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1211 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1212 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1213
1214 # Note, ONU ID and UNI intf set in add_uni_port method
1215 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1216 ani_ports=[self._pon])
1217
1218 # Code to Run OMCI Test Action
1219 kwargs_omci_test_action = {
1220 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1221 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1222 }
1223 serial_number = device.serial_number
1224 self._test_request = OmciTestRequest(self.core_proxy,
1225 self.omci_agent, self.device_id,
1226 AniG, serial_number,
1227 self.logical_device_id,
1228 exclusive=False,
1229 **kwargs_omci_test_action)
1230
1231 self.enabled = True
1232 else:
1233 self.logger.info('onu-already-activated')
1234 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001235
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001237}
1238
1239// doStateConnected get the device info and update to voltha core
1240// for comparison of the original method (not that easy to uncomment): compare here:
1241// voltha-openolt-adapter/adaptercore/device_handler.go
1242// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001244
dbainbri4d3a0dc2020-12-02 00:33:42 +00001245 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301246 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001247 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001248 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001249}
1250
1251// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001253
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301255 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001256 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001258
1259 /*
1260 // Synchronous call to update device state - this method is run in its own go routine
1261 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1262 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001263 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 +00001264 return err
1265 }
1266 return nil
1267 */
1268}
1269
1270// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001272
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001274 var err error
1275
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001276 device := dh.device
1277 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001278 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001280 e.Cancel(err)
1281 return
1282 }
1283
1284 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001286 /*
1287 // Update the all ports state on that device to disable
1288 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001289 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001290 return er
1291 }
1292
1293 //Update the device oper state and connection status
1294 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1295 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1296 dh.device = cloned
1297
1298 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001299 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001300 return er
1301 }
1302
1303 //get the child device for the parent device
1304 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1305 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001306 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001307 return err
1308 }
1309 for _, onuDevice := range onuDevices.Items {
1310
1311 // Update onu state as down in onu adapter
1312 onuInd := oop.OnuIndication{}
1313 onuInd.OperState = "down"
1314 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1315 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1316 if er != nil {
1317 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001318 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001319 //Do not return here and continue to process other ONUs
1320 }
1321 }
1322 // * Discovered ONUs entries need to be cleared , since after OLT
1323 // is up, it starts sending discovery indications again* /
1324 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001325 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001326 return nil
1327 */
Himani Chawla4d908332020-08-31 12:30:20 +05301328 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001330 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001331}
1332
Himani Chawla6d2ae152020-09-02 13:11:20 +05301333// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001334// #################################################################################
1335
1336// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301337// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001338
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001339//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001341 dh.lockDevice.RLock()
1342 pOnuDeviceEntry := dh.pOnuOmciDevice
1343 if aWait && pOnuDeviceEntry == nil {
1344 //keep the read sema short to allow for subsequent write
1345 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001346 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001347 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1348 // so it might be needed to wait here for that event with some timeout
1349 select {
1350 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001352 return nil
1353 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001354 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001355 // if written now, we can return the written value without sema
1356 return dh.pOnuOmciDevice
1357 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001358 }
mpagenko3af1f032020-06-10 08:53:41 +00001359 dh.lockDevice.RUnlock()
1360 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001361}
1362
Himani Chawla6d2ae152020-09-02 13:11:20 +05301363//setOnuDeviceEntry sets the ONU device entry within the handler
1364func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301365 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001366 dh.lockDevice.Lock()
1367 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001368 dh.pOnuOmciDevice = apDeviceEntry
1369 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001370 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301371 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001372}
1373
Himani Chawla6d2ae152020-09-02 13:11:20 +05301374//addOnuDeviceEntry creates a new ONU device or returns the existing
1375func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001376 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001377
dbainbri4d3a0dc2020-12-02 00:33:42 +00001378 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001379 if deviceEntry == nil {
1380 /* costum_me_map in python code seems always to be None,
1381 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1382 /* also no 'clock' argument - usage open ...*/
1383 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001384 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001385 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001386 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301387 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001388 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301389 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001390 // fire deviceEntry ready event to spread to possibly waiting processing
1391 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001392 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001393 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001394 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001395 }
1396 // might be updated with some error handling !!!
1397 return nil
1398}
1399
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1401 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001402 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1403
1404 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001405
dbainbri4d3a0dc2020-12-02 00:33:42 +00001406 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001407 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001408 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001409 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1410 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001411 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001412 if err := dh.storePersistentData(ctx); err != nil {
1413 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001414 log.Fields{"device-id": dh.deviceID, "err": err})
1415 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001416 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001417 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001419 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1420 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001422 }
1423 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001424 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001425 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001426
1427 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 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 +00001429 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001430 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001431 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001432 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001433 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1434 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1435 // 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 +00001436 // 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 +00001437 // so let's just try to keep it simple ...
1438 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001440 if err != nil || device == nil {
1441 //TODO: needs to handle error scenarios
1442 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1443 return errors.New("Voltha Device not found")
1444 }
1445 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001446
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001448 return err
mpagenko3af1f032020-06-10 08:53:41 +00001449 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001450
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001451 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452
1453 /* this might be a good time for Omci Verify message? */
1454 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001456 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001457 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001458 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459
1460 /* give the handler some time here to wait for the OMCi verification result
1461 after Timeout start and try MibUpload FSM anyway
1462 (to prevent stopping on just not supported OMCI verification from ONU) */
1463 select {
1464 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001468 }
1469
1470 /* In py code it looks earlier (on activate ..)
1471 # Code to Run OMCI Test Action
1472 kwargs_omci_test_action = {
1473 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1474 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1475 }
1476 serial_number = device.serial_number
1477 self._test_request = OmciTestRequest(self.core_proxy,
1478 self.omci_agent, self.device_id,
1479 AniG, serial_number,
1480 self.logical_device_id,
1481 exclusive=False,
1482 **kwargs_omci_test_action)
1483 ...
1484 # Start test requests after a brief pause
1485 if not self._test_request_started:
1486 self._test_request_started = True
1487 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1488 reactor.callLater(tststart, self._test_request.start_collector)
1489
1490 */
1491 /* which is then: in omci_test_request.py : */
1492 /*
1493 def start_collector(self, callback=None):
1494 """
1495 Start the collection loop for an adapter if the frequency > 0
1496
1497 :param callback: (callable) Function to call to collect PM data
1498 """
1499 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1500 if callback is None:
1501 callback = self.perform_test_omci
1502
1503 if self.lc is None:
1504 self.lc = LoopingCall(callback)
1505
1506 if self.default_freq > 0:
1507 self.lc.start(interval=self.default_freq / 10)
1508
1509 def perform_test_omci(self):
1510 """
1511 Perform the initial test request
1512 """
1513 ani_g_entities = self._device.configuration.ani_g_entities
1514 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1515 is not None else None
1516 self._entity_id = ani_g_entities_ids[0]
1517 self.logger.info('perform-test', entity_class=self._entity_class,
1518 entity_id=self._entity_id)
1519 try:
1520 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1521 result = yield self._device.omci_cc.send(frame)
1522 if not result.fields['omci_message'].fields['success_code']:
1523 self.logger.info('Self-Test Submitted Successfully',
1524 code=result.fields[
1525 'omci_message'].fields['success_code'])
1526 else:
1527 raise TestFailure('Test Failure: {}'.format(
1528 result.fields['omci_message'].fields['success_code']))
1529 except TimeoutError as e:
1530 self.deferred.errback(failure.Failure(e))
1531
1532 except Exception as e:
1533 self.logger.exception('perform-test-Error', e=e,
1534 class_id=self._entity_class,
1535 entity_id=self._entity_id)
1536 self.deferred.errback(failure.Failure(e))
1537
1538 */
1539
1540 // PM related heartbeat??? !!!TODO....
1541 //self._heartbeat.enabled = True
1542
mpagenko1cc3cb42020-07-27 15:24:38 +00001543 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1544 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1545 * 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 +05301546 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001547 */
1548 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001549 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001550 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001551 if pMibUlFsm.Is(ulStDisabled) {
1552 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553 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 +00001554 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301555 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301557 //Determine ONU status and start/re-start MIB Synchronization tasks
1558 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001559 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301560 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001561 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 +00001562 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001563 }
Himani Chawla4d908332020-08-31 12:30:20 +05301564 } else {
1565 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566 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 +00001567 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301568 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001570 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001571 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001573 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001574 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001575 }
1576 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001578 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001579 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001580
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001581 if !dh.getCollectorIsRunning() {
1582 // Start PM collector routine
1583 go dh.startCollector(ctx)
1584 }
Himani Chawla1472c682021-03-17 17:11:14 +05301585 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301586 go dh.startAlarmManager(ctx)
1587 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301588
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 return nil
1590}
1591
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001593 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001594 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001595 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001597
mpagenko900ee4b2020-10-12 11:56:34 +00001598 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1599 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1600 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001601 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001603 log.Fields{"device-id": dh.deviceID, "error": err})
1604 // abort: system behavior is just unstable ...
1605 return err
1606 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001607 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 _ = 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 +00001609
1610 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1611 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1612 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001614 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001616 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001617 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001619
1620 //TODO!!! remove existing traffic profiles
1621 /* from py code, if TP's exist, remove them - not yet implemented
1622 self._tp = dict()
1623 # Let TP download happen again
1624 for uni_id in self._tp_service_specific_task:
1625 self._tp_service_specific_task[uni_id].clear()
1626 for uni_id in self._tech_profile_download_done:
1627 self._tech_profile_download_done[uni_id].clear()
1628 */
1629
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001631
mpagenkofc4f56e2020-11-04 17:17:49 +00001632 dh.ReadyForSpecificOmciConfig = false
1633
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001635 // abort: system behavior is just unstable ...
1636 return err
1637 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001639 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001641 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001642 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001644 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001645 // abort: system behavior is just unstable ...
1646 return err
1647 }
1648 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001650 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001651 return nil
1652}
1653
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001654func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001655 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1656 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1657 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1658 // and using the stop/reset event should never harm
1659
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001661 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001663 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1664 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001665 if includingMibSyncFsm {
1666 //the MibSync FSM might be active all the ONU-active time,
1667 // hence it must be stopped unconditionally
1668 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1669 if pMibUlFsm != nil {
1670 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1671 }
mpagenko900ee4b2020-10-12 11:56:34 +00001672 }
1673 //MibDownload may run
1674 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1675 if pMibDlFsm != nil {
1676 _ = pMibDlFsm.Event(dlEvReset)
1677 }
1678 //port lock/unlock FSM's may be active
1679 if dh.pUnlockStateFsm != nil {
1680 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1681 }
1682 if dh.pLockStateFsm != nil {
1683 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1684 }
1685 //techProfile related PonAniConfigFsm FSM may be active
1686 if dh.pOnuTP != nil {
1687 // should always be the case here
1688 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1689 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001690 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko7d6bb022021-03-11 15:07:55 +00001691 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing()
Girish Gowdra041dcb32020-11-16 16:54:30 -08001692 }
mpagenko900ee4b2020-10-12 11:56:34 +00001693 }
1694 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001695 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001696 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001697 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1698 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001699 dh.lockVlanConfig.RUnlock()
1700 //reset of all Fsm is always accompanied by global persistency data removal
1701 // no need to remove specific data
1702 pVlanFilterFsm.RequestClearPersistency(false)
1703 //ensure the FSM processing is stopped in case waiting for some response
1704 pVlanFilterFsm.CancelProcessing()
mpagenkof1fc3862021-02-16 10:09:52 +00001705 } else {
1706 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001707 }
1708 }
1709 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001710 if dh.getCollectorIsRunning() {
1711 // Stop collector routine
1712 dh.stopCollector <- true
1713 }
Himani Chawla1472c682021-03-17 17:11:14 +05301714 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301715 dh.stopAlarmManager <- true
1716 }
1717
mpagenko80622a52021-02-09 16:53:23 +00001718 //reset a possibly running upgrade FSM
1719 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1720 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1721 dh.lockUpgradeFsm.RLock()
1722 if dh.pOnuUpradeFsm != nil {
mpagenko59498c12021-03-18 14:15:15 +00001723 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1724 if pUpgradeStatemachine != nil {
1725 if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
1726 dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
1727 }
1728 _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
1729 }
1730 //else the FSM seems already to be in some released state
mpagenko80622a52021-02-09 16:53:23 +00001731 }
1732 dh.lockUpgradeFsm.RUnlock()
1733
mpagenko7d6bb022021-03-11 15:07:55 +00001734 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001735 return nil
1736}
1737
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1739 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 +05301740
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001741 // store persistent data collected during MIB upload processing
1742 if err := dh.storePersistentData(ctx); err != nil {
1743 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1744 log.Fields{"device-id": dh.deviceID, "err": err})
1745 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001746 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001747 dh.addAllUniPorts(ctx)
1748
mpagenkoa40e99a2020-11-17 13:50:39 +00001749 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1750 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1751 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1752 * disable/enable toggling here to allow traffic
1753 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1754 * like the py comment says:
1755 * # start by locking all the unis till mib sync and initial mib is downloaded
1756 * # this way we can capture the port down/up events when we are ready
1757 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301758
mpagenkoa40e99a2020-11-17 13:50:39 +00001759 // Init Uni Ports to Admin locked state
1760 // *** should generate UniLockStateDone event *****
1761 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001763 } else { //LockStateFSM already init
1764 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001766 }
1767}
1768
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1770 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301771 /* Mib download procedure -
1772 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1773 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001775 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001776 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001777 return
1778 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301779 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1780 if pMibDlFsm != nil {
1781 if pMibDlFsm.Is(dlStDisabled) {
1782 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001783 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 +05301784 // maybe try a FSM reset and then again ... - TODO!!!
1785 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301787 // maybe use more specific states here for the specific download steps ...
1788 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301790 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301792 //Begin MIB data download (running autonomously)
1793 }
1794 }
1795 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001797 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301798 // maybe try a FSM reset and then again ... - TODO!!!
1799 }
1800 /***** Mib download started */
1801 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301803 }
1804}
1805
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1807 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301808 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001809 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001811 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001812 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1813 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1814 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1815 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301817 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1818 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001819 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301820 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301822 }
1823 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301825 log.Fields{"device-id": dh.deviceID})
1826 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001827 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001828
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07001829 if !dh.getCollectorIsRunning() {
1830 // Start PM collector routine
1831 go dh.startCollector(ctx)
1832 }
1833 if !dh.getAlarmManagerIsRunning(ctx) {
1834 go dh.startAlarmManager(ctx)
1835 }
1836
Girish Gowdrae0140f02021-02-02 16:55:09 -08001837 // Initialize classical L2 PM Interval Counters
1838 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1839 // There is no way we should be landing here, but if we do then
1840 // there is nothing much we can do about this other than log error
1841 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1842 }
1843
mpagenkofc4f56e2020-11-04 17:17:49 +00001844 dh.ReadyForSpecificOmciConfig = true
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001845
1846 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1847 if pDevEntry == nil {
1848 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1849 return
1850 }
1851 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
1852 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1853 log.Fields{"device-id": dh.deviceID})
1854 go dh.reconcileDeviceTechProf(ctx)
1855 // reconcilement will be continued after ani config is done
1856 } else {
1857 // *** should generate UniUnlockStateDone event *****
1858 if dh.pUnlockStateFsm == nil {
1859 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1860 } else { //UnlockStateFSM already init
1861 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1862 dh.runUniLockFsm(ctx, false)
1863 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301864 }
1865}
1866
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1868 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301869
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001870 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301872 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1874 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001875 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001877 return
1878 }
1879 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 if err := dh.storePersistentData(ctx); err != nil {
1881 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001882 log.Fields{"device-id": dh.deviceID, "err": err})
1883 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301884 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 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 +05301886 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001888 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301889 }
1890}
1891
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1893 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001894 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001896 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1897 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001899 }
1900
dbainbri4d3a0dc2020-12-02 00:33:42 +00001901 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001902 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001903 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001904
1905 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001907
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001909 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001911 return
1912 }
1913 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 if err := dh.storePersistentData(ctx); err != nil {
1915 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001916 log.Fields{"device-id": dh.deviceID, "err": err})
1917 }
mpagenko900ee4b2020-10-12 11:56:34 +00001918}
1919
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1921 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001922 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001924 voltha.OperStatus_ACTIVE); err != nil {
1925 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001926 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001927 }
1928
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001930 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001931 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001933
1934 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001936
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001938 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001940 return
1941 }
1942 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 if err := dh.storePersistentData(ctx); err != nil {
1944 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001945 log.Fields{"device-id": dh.deviceID, "err": err})
1946 }
mpagenko900ee4b2020-10-12 11:56:34 +00001947}
1948
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001950 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001952 // attention: the device reason update is done based on ONU-UNI-Port related activity
1953 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001954 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001955 // 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 +00001956 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301957 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001958 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001960 }
1961 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001963 // attention: the device reason update is done based on ONU-UNI-Port related activity
1964 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001965 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001966 // 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 +00001967 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001968 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001969 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301970}
1971
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1973 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001974 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301975 // attention: the device reason update is done based on ONU-UNI-Port related activity
1976 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301977
mpagenkof1fc3862021-02-16 10:09:52 +00001978 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001979 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001980 // which may be the case from some previous actvity on another UNI Port of the ONU
1981 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001982 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1983 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001984 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001985 }
1986 }
1987 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001988 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001989 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001991 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301992 }
mpagenkof1fc3862021-02-16 10:09:52 +00001993
1994 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1995 //events that request KvStore write
1996 if err := dh.storePersistentData(ctx); err != nil {
1997 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1998 log.Fields{"device-id": dh.deviceID, "err": err})
1999 }
2000 } else {
2001 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2002 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002003 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302004}
2005
Himani Chawla6d2ae152020-09-02 13:11:20 +05302006//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302008 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002009 case MibDatabaseSync:
2010 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002012 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002013 case UniLockStateDone:
2014 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002016 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002017 case MibDownloadDone:
2018 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002020 }
2021 case UniUnlockStateDone:
2022 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002024 }
mpagenko900ee4b2020-10-12 11:56:34 +00002025 case UniEnableStateDone:
2026 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002028 }
2029 case UniDisableStateDone:
2030 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002032 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002033 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002034 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002036 }
mpagenkof1fc3862021-02-16 10:09:52 +00002037 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002038 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002040 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002041 default:
2042 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002044 }
2045 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002046}
2047
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002049 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002050 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302051 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002052 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002053 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002054 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302055 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002057 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002059 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002060 //store UniPort with the System-PortNumber key
2061 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002062 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002063 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2065 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002066 } //error logging already within UniPort method
2067 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002069 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002070 }
2071 }
2072}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002073
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002074func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2075 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2076 if pDevEntry == nil {
2077 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2078 return
2079 }
2080 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2081 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2082 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2083 for _, mgmtEntityID := range pptpInstKeys {
2084 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2085 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2086 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2087 i++
2088 }
2089 } else {
2090 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2091 }
2092 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2093 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2094 for _, mgmtEntityID := range veipInstKeys {
2095 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2096 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2097 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2098 i++
2099 }
2100 } else {
2101 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2102 }
2103 if i == 0 {
2104 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2105 }
2106}
2107
mpagenko3af1f032020-06-10 08:53:41 +00002108// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002110 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302111 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002112 // with following remark:
2113 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2114 // # load on the core
2115
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002116 // 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 +00002117
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002118 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002119 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302120 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002121 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302122 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002123 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002124 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125 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 +00002126 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002128 }
mpagenko3af1f032020-06-10 08:53:41 +00002129 }
2130 }
2131}
2132
2133// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002135 // compare enableUniPortStateUpdate() above
2136 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2137 for uniNo, uniPort := range dh.uniEntityMap {
2138 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302139 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302141 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002142 if !dh.isReconciling() {
2143 //maybe also use getter functions on uniPort - perhaps later ...
2144 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2145 } else {
2146 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2147 }
2148
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002149 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002150 }
2151}
2152
2153// ONU_Active/Inactive announcement on system KAFKA bus
2154// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002155func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002156 var de voltha.DeviceEvent
2157 eventContext := make(map[string]string)
2158 //Populating event context
2159 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002161 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002162 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302163 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002164 }
2165 oltSerialNumber := parentDevice.SerialNumber
2166
2167 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2168 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2169 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302170 eventContext["olt-serial-number"] = oltSerialNumber
2171 eventContext["device-id"] = aDeviceID
2172 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002174 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002175
2176 /* Populating device event body */
2177 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302178 de.ResourceId = aDeviceID
2179 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002180 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2181 de.Description = fmt.Sprintf("%s Event - %s - %s",
2182 cEventObjectType, cOnuActivatedEvent, "Raised")
2183 } else {
2184 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2185 de.Description = fmt.Sprintf("%s Event - %s - %s",
2186 cEventObjectType, cOnuActivatedEvent, "Cleared")
2187 }
2188 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2190 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302191 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002192 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302194 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002195}
2196
Himani Chawla4d908332020-08-31 12:30:20 +05302197// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002199 chLSFsm := make(chan Message, 2048)
2200 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302201 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002203 sFsmName = "LockStateFSM"
2204 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002206 sFsmName = "UnLockStateFSM"
2207 }
mpagenko3af1f032020-06-10 08:53:41 +00002208
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002210 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002212 return
2213 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002215 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002216 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302217 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002218 dh.pLockStateFsm = pLSFsm
2219 } else {
2220 dh.pUnlockStateFsm = pLSFsm
2221 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002223 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002225 }
2226}
2227
2228// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002230 /* Uni Port lock/unlock procedure -
2231 ***** should run via 'adminDone' state and generate the argument requested event *****
2232 */
2233 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302234 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002235 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2236 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2237 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002238 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302239 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002240 }
2241 } else {
2242 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2243 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2244 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002245 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302246 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002247 }
2248 }
2249 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002250 if pLSStatemachine.Is(uniStDisabled) {
2251 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002253 // maybe try a FSM reset and then again ... - TODO!!!
2254 } else {
2255 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002257 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002258 }
2259 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002261 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002262 // maybe try a FSM reset and then again ... - TODO!!!
2263 }
2264 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002266 // maybe try a FSM reset and then again ... - TODO!!!
2267 }
2268}
2269
mpagenko80622a52021-02-09 16:53:23 +00002270// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002271func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002272 //in here lockUpgradeFsm is already locked
2273 chUpgradeFsm := make(chan Message, 2048)
2274 var sFsmName = "OnuSwUpgradeFSM"
2275 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002276 if apDevEntry.PDevOmciCC == nil {
2277 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2278 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002279 }
mpagenko15ff4a52021-03-02 10:09:20 +00002280 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002281 sFsmName, chUpgradeFsm)
2282 if dh.pOnuUpradeFsm != nil {
2283 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2284 if pUpgradeStatemachine != nil {
2285 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2286 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2287 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2288 // maybe try a FSM reset and then again ... - TODO!!!
2289 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2290 }
2291 /***** LockStateFSM started */
2292 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2293 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2294 } else {
2295 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2296 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2297 // maybe try a FSM reset and then again ... - TODO!!!
2298 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2299 }
2300 } else {
2301 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2302 // maybe try a FSM reset and then again ... - TODO!!!
2303 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2304 }
2305 } else {
2306 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2307 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2308 }
2309 return nil
2310}
2311
2312// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2313func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2314 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2315 "device-id": dh.deviceID})
2316 dh.lockUpgradeFsm.Lock()
2317 defer dh.lockUpgradeFsm.Unlock()
2318 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2319}
2320
mpagenko15ff4a52021-03-02 10:09:20 +00002321// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2322func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2323 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2324 if pDevEntry == nil {
2325 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2326 return
2327 }
2328
2329 dh.lockUpgradeFsm.RLock()
2330 defer dh.lockUpgradeFsm.RUnlock()
2331 if dh.pOnuUpradeFsm != nil {
2332 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2333 if pUpgradeStatemachine != nil {
2334 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2335 // (some manual forced commit could do without)
2336 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002337 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002338 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2339 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2340 return
2341 }
2342 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2343 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2344 } else {
2345 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2346 log.Fields{"device-id": dh.deviceID})
2347 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2348 return
2349 }
2350 }
2351 }
2352 } else {
2353 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2354 }
2355}
2356
Himani Chawla6d2ae152020-09-02 13:11:20 +05302357//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002359
2360 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002361 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002362 kvbackend := &db.Backend{
2363 Client: dh.pOpenOnuAc.kvClient,
2364 StoreType: dh.pOpenOnuAc.KVStoreType,
2365 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002366 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002367 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2368 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002369
mpagenkoaf801632020-07-03 10:00:42 +00002370 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002371}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002372func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302373 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002374
mpagenkodff5dda2020-08-28 11:52:01 +00002375 for _, field := range flow.GetOfbFields(apFlowItem) {
2376 switch field.Type {
2377 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2378 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002379 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002380 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2381 }
mpagenko01e726e2020-10-23 09:45:29 +00002382 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002383 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2384 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302385 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002386 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302387 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2388 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002389 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2390 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002391 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2392 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302393 return
mpagenkodff5dda2020-08-28 11:52:01 +00002394 }
2395 }
mpagenko01e726e2020-10-23 09:45:29 +00002396 */
mpagenkodff5dda2020-08-28 11:52:01 +00002397 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2398 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302399 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002400 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302401 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002402 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302403 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002404 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302406 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002407 }
2408 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2409 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302410 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002412 "PCP": loAddPcp})
2413 }
2414 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2415 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002417 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2418 }
2419 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2420 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002421 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002422 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2423 }
2424 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2425 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002427 "IPv4-DST": field.GetIpv4Dst()})
2428 }
2429 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2430 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002431 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002432 "IPv4-SRC": field.GetIpv4Src()})
2433 }
2434 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2435 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002437 "Metadata": field.GetTableMetadata()})
2438 }
2439 /*
2440 default:
2441 {
2442 //all other entires ignored
2443 }
2444 */
2445 }
2446 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302447}
mpagenkodff5dda2020-08-28 11:52:01 +00002448
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002450 for _, action := range flow.GetActions(apFlowItem) {
2451 switch action.Type {
2452 /* not used:
2453 case of.OfpActionType_OFPAT_OUTPUT:
2454 {
mpagenko01e726e2020-10-23 09:45:29 +00002455 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002456 "Output": action.GetOutput()})
2457 }
2458 */
2459 case of.OfpActionType_OFPAT_PUSH_VLAN:
2460 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002462 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2463 }
2464 case of.OfpActionType_OFPAT_SET_FIELD:
2465 {
2466 pActionSetField := action.GetSetField()
2467 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002468 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002469 "OxcmClass": pActionSetField.Field.OxmClass})
2470 }
2471 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302472 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302474 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002475 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302476 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302478 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002479 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002480 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002481 "Type": pActionSetField.Field.GetOfbField().Type})
2482 }
2483 }
2484 /*
2485 default:
2486 {
2487 //all other entires ignored
2488 }
2489 */
2490 }
2491 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302492}
2493
2494//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302496 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2497 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2498 var loAddPcp, loSetPcp uint8
2499 var loIPProto uint32
2500 /* the TechProfileId is part of the flow Metadata - compare also comment within
2501 * OLT-Adapter:openolt_flowmgr.go
2502 * Metadata 8 bytes:
2503 * Most Significant 2 Bytes = Inner VLAN
2504 * Next 2 Bytes = Tech Profile ID(TPID)
2505 * Least Significant 4 Bytes = Port ID
2506 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2507 * subscriber related flows.
2508 */
2509
dbainbri4d3a0dc2020-12-02 00:33:42 +00002510 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302511 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302513 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002514 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302515 }
mpagenko551a4d42020-12-08 18:09:20 +00002516 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002517 loCookie := apFlowItem.GetCookie()
2518 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002520 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302521
dbainbri4d3a0dc2020-12-02 00:33:42 +00002522 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002523 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302524 if loIPProto == 2 {
2525 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2526 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002527 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2528 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302529 return nil
2530 }
mpagenko01e726e2020-10-23 09:45:29 +00002531 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002532 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002533
2534 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002535 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002536 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2537 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2538 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2539 //TODO!!: Use DeviceId within the error response to rwCore
2540 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002541 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002542 }
2543 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002544 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002545 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2546 } else {
2547 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2548 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2549 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302550 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002551 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002553 }
mpagenko9a304ea2020-12-16 15:54:01 +00002554
2555 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002556 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002557 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302558 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002559 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002560 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002561 dh.lockVlanConfig.RUnlock()
2562 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002563 }
mpagenkof1fc3862021-02-16 10:09:52 +00002564 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002565 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002566 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002567}
2568
2569//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002571 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2572 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2573 //no extra check is done on the rule parameters
2574 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2575 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2576 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2577 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002578 // - 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 +00002579 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002580 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002581
2582 /* TT related temporary workaround - should not be needed anymore
2583 for _, field := range flow.GetOfbFields(apFlowItem) {
2584 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2585 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002586 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002587 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2588 if loIPProto == 2 {
2589 // 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 +00002590 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002591 log.Fields{"device-id": dh.deviceID})
2592 return nil
2593 }
2594 }
2595 } //for all OfbFields
2596 */
2597
mpagenko9a304ea2020-12-16 15:54:01 +00002598 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002599 dh.lockVlanConfig.RLock()
2600 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002601 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002602 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002603 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002604 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002605 log.Fields{"device-id": dh.deviceID})
2606 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002607 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002609
mpagenko01e726e2020-10-23 09:45:29 +00002610 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002611}
2612
Himani Chawla26e555c2020-08-31 12:30:20 +05302613// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002614// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002615func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002616 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002617 chVlanFilterFsm := make(chan Message, 2048)
2618
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002620 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302622 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002623 }
2624
dbainbri4d3a0dc2020-12-02 00:33:42 +00002625 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002626 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2627 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002628 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002629 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002630 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2631 // (from parallel processing)
2632 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302633 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002634 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2635 if pVlanFilterStatemachine != nil {
2636 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2637 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002638 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302639 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002640 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302641 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002642 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302643 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2644 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002645 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002647 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302648 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002649 }
2650 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002651 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002652 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302653 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002654 }
2655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002656 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002657 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302658 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002659 }
2660 return nil
2661}
2662
mpagenkofc4f56e2020-11-04 17:17:49 +00002663//VerifyVlanConfigRequest checks on existence of a given uniPort
2664// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002665func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002666 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2667 var pCurrentUniPort *onuUniPort
2668 for _, uniPort := range dh.uniEntityMap {
2669 // only if this port is validated for operState transfer
2670 if uniPort.uniID == uint8(aUniID) {
2671 pCurrentUniPort = uniPort
2672 break //found - end search loop
2673 }
2674 }
2675 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002676 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002677 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2678 return
2679 }
mpagenko551a4d42020-12-08 18:09:20 +00002680 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002681}
2682
mpagenkodff5dda2020-08-28 11:52:01 +00002683//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002684func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002685 //TODO!! verify and start pending flow configuration
2686 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2687 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002688
2689 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302690 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002691 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002692 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2693 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2694 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002695 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2696 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2697 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2698 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2699 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2700 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2701 } else {
2702 /***** UniVlanConfigFsm continued */
2703 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2704 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2705 "UniPort": apUniPort.portNo})
2706 }
2707 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2708 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2709 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2710 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2711 } else {
2712 /***** UniVlanConfigFsm continued */
2713 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2714 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2715 "UniPort": apUniPort.portNo})
2716 }
mpagenkodff5dda2020-08-28 11:52:01 +00002717 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002718 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2719 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002720 "UniPort": apUniPort.portNo})
2721 }
2722 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002723 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2724 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2725 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002726 }
2727 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002728 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002729 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002730 }
mpagenkof1fc3862021-02-16 10:09:52 +00002731 } else {
2732 dh.lockVlanConfig.RUnlock()
2733 }
mpagenkodff5dda2020-08-28 11:52:01 +00002734}
2735
2736//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2737// 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 +00002738func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2739 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002740 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2741 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002742 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302743 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002744 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002745}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002746
Girish Gowdra26a40922021-01-29 17:14:34 -08002747//ProcessPendingTpDelete processes any pending TP delete (if available)
2748func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2749 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2750 if apUniPort == nil {
2751 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2752 return
2753 }
2754 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2755 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2756 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2757 if pAniConfigStatemachine != nil {
2758 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2759 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2760 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2761 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2762 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2763 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2764 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2765 return
2766 }
2767 } else {
2768 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2769 return
2770 }
2771 }
2772 return
2773 }
2774}
2775
mpagenkof1fc3862021-02-16 10:09:52 +00002776//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2777func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2778 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2779 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2780 // obviously then parallel processing on the cancel must be avoided
2781 // deadline context to ensure completion of background routines waited for
2782 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2783 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2784 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2785
2786 aPDevEntry.resetKvProcessingErrorIndication()
2787 var wg sync.WaitGroup
2788 wg.Add(1) // for the 1 go routine to finish
2789
2790 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2791 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2792
2793 return aPDevEntry.getKvProcessingErrorIndication()
2794}
2795
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002796//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2797//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002798func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2799 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002800
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002801 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002803 return nil
2804 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002806
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002808 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002810 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2811 }
2812 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2813
mpagenkof1fc3862021-02-16 10:09:52 +00002814 if aWriteToKvStore {
2815 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2816 }
2817 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002818}
2819
dbainbri4d3a0dc2020-12-02 00:33:42 +00002820func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002821 defer cancel() //ensure termination of context (may be pro forma)
2822 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002823 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002824 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002825}
2826
dbainbri4d3a0dc2020-12-02 00:33:42 +00002827func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002828
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002829 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002830 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002831 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002832 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2833 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002834 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002835 return err
2836 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002837 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002838 return nil
2839 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002840 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002841 return nil
2842}
2843
dbainbri4d3a0dc2020-12-02 00:33:42 +00002844func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2845 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002846 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002848 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2849 }
mpagenkof1fc3862021-02-16 10:09:52 +00002850 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002851}
2852
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002853func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2854 var errStr string = ""
2855 for _, err := range errS {
2856 if err != nil {
2857 errStr = errStr + err.Error() + " "
2858 }
2859 }
2860 if errStr != "" {
2861 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2862 }
2863 return nil
2864}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002865
2866// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2867func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2868 dh.lockDevice.RLock()
2869 defer dh.lockDevice.RUnlock()
2870 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2871 return uniPort.entityID, nil
2872 }
2873 return 0, errors.New("error-fetching-uni-port")
2874}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002875
2876// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002877func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2878 var errorsList []error
2879 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 -08002880
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002881 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2882 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2883 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2884
2885 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2886 // successfully.
2887 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2888 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2889 if len(errorsList) > 0 {
2890 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2891 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002892 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002893 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2894 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002895}
2896
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002897func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2898 var err error
2899 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002900 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002901
2902 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2903 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2904 errorsList = append(errorsList, err)
2905 }
2906 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002907 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002908
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002909 return errorsList
2910}
2911
2912func (dh *deviceHandler) handleGroupPmConfigUpdates(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-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002916 // Check if group metric related config is updated
2917 for _, v := range pmConfigs.Groups {
2918 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2919 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2920 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2921
2922 if ok && m.frequency != v.GroupFreq {
2923 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2924 errorsList = append(errorsList, err)
2925 }
2926 }
2927 if ok && m.enabled != v.Enabled {
2928 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2929 errorsList = append(errorsList, err)
2930 }
2931 }
2932 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002933 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002934 return errorsList
2935}
2936
2937func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2938 var err error
2939 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002940 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002941 // Check if standalone metric related config is updated
2942 for _, v := range pmConfigs.Metrics {
2943 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002944 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002945 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2946
2947 if ok && m.frequency != v.SampleFreq {
2948 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2949 errorsList = append(errorsList, err)
2950 }
2951 }
2952 if ok && m.enabled != v.Enabled {
2953 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2954 errorsList = append(errorsList, err)
2955 }
2956 }
2957 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002958 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002959 return errorsList
2960}
2961
2962// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002963func (dh *deviceHandler) startCollector(ctx context.Context) {
2964 logger.Debugf(ctx, "startingCollector")
2965
2966 // Start routine to process OMCI GET Responses
2967 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002968 // Initialize the next metric collection time.
2969 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2970 // reset like onu rebooted.
2971 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002972 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002973 for {
2974 select {
2975 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002976 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002977 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002978 // Stop the L2 PM FSM
2979 go func() {
2980 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2981 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2982 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2983 }
2984 } else {
2985 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2986 }
2987 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002988 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2989 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2990 }
2991 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2992 dh.pOnuMetricsMgr.stopTicks <- true
2993 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002994
Girish Gowdrae09a6202021-01-12 18:10:59 -08002995 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002996 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2997 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2998 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2999 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3000 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003001 // Update the next metric collection time.
3002 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003003 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003004 } else {
3005 if dh.pmConfigs.Grouped { // metrics are managed as a group
3006 // parse through the group and standalone metrics to see it is time to collect their metrics
3007 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003008
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003009 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3010 // 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 -08003011 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3012 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003013 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3014 }
3015 }
3016 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3017 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3018 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3019 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3020 }
3021 }
3022 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3023
3024 // parse through the group and update the next metric collection time
3025 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3026 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3027 // 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 -08003028 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3029 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003030 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3031 }
3032 }
3033 // parse through the standalone metrics and update the next metric collection time
3034 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3035 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3036 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3037 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3038 }
3039 }
3040 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3041 } /* else { // metrics are not managed as a group
3042 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3043 } */
3044 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003045 }
3046 }
3047}
kesavandfdf77632021-01-26 23:40:33 -05003048
3049func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3050
3051 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3052 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3053}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003054
mpagenkof1fc3862021-02-16 10:09:52 +00003055func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3056 if pFsm == nil {
3057 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003058 }
mpagenkof1fc3862021-02-16 10:09:52 +00003059 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003060}
3061
mpagenkof1fc3862021-02-16 10:09:52 +00003062func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3063 var pFsm *fsm.FSM
3064 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3065 switch omciFsm {
3066 case cUploadFsm:
3067 {
3068 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3069 }
3070 case cDownloadFsm:
3071 {
3072 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3073 }
3074 case cUniLockFsm:
3075 {
3076 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3077 }
3078 case cUniUnLockFsm:
3079 {
3080 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3081 }
3082 case cL2PmFsm:
3083 {
3084 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3085 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3086 } else {
3087 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003088 }
3089 }
mpagenko80622a52021-02-09 16:53:23 +00003090 case cOnuUpgradeFsm:
3091 {
3092 dh.lockUpgradeFsm.RLock()
3093 defer dh.lockUpgradeFsm.RUnlock()
3094 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3095 }
mpagenkof1fc3862021-02-16 10:09:52 +00003096 default:
3097 {
3098 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3099 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3100 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003101 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003102 }
mpagenkof1fc3862021-02-16 10:09:52 +00003103 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003104}
3105
mpagenkof1fc3862021-02-16 10:09:52 +00003106func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3107 for _, v := range dh.pOnuTP.pAniConfigFsm {
3108 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003109 return false
3110 }
3111 }
3112 return true
3113}
3114
mpagenkof1fc3862021-02-16 10:09:52 +00003115func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3116 dh.lockVlanConfig.RLock()
3117 defer dh.lockVlanConfig.RUnlock()
3118 for _, v := range dh.UniVlanConfigFsmMap {
3119 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3120 return false
3121 }
3122 }
3123 return true //FSM not active - so there is no activity on omci
3124}
3125
3126func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3127 dh.lockVlanConfig.RLock()
3128 defer dh.lockVlanConfig.RUnlock()
3129 for _, v := range dh.UniVlanConfigFsmMap {
3130 if v.pAdaptFsm.pFsm != nil {
3131 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3132 return true //there is at least one VLAN FSM with some active configuration
3133 }
3134 }
3135 }
3136 return false //there is no VLAN FSM with some active configuration
3137}
3138
3139func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3140 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3141 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3142 return false
3143 }
3144 }
3145 // a further check is done to identify, if at least some data traffic related configuration exists
3146 // 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])
3147 return dh.checkUserServiceExists(ctx)
3148}
3149
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003150func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3151 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3152 if err := dh.resetFsms(ctx, false); err != nil {
3153 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3154 // TODO: fatal error reset ONU, delete deviceHandler!
3155 return
3156 }
3157 if !dh.getCollectorIsRunning() {
3158 // Start PM collector routine
3159 go dh.startCollector(ctx)
3160 }
Himani Chawla1472c682021-03-17 17:11:14 +05303161 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303162 go dh.startAlarmManager(ctx)
3163 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003164 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003165 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003166}
3167
3168func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3169 dh.mutexCollectorFlag.Lock()
3170 dh.collectorIsRunning = flagValue
3171 dh.mutexCollectorFlag.Unlock()
3172}
3173
3174func (dh *deviceHandler) getCollectorIsRunning() bool {
3175 dh.mutexCollectorFlag.RLock()
3176 flagValue := dh.collectorIsRunning
3177 dh.mutexCollectorFlag.RUnlock()
3178 return flagValue
3179}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303180
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303181func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3182 dh.mutextAlarmManagerFlag.Lock()
3183 dh.alarmManagerIsRunning = flagValue
3184 dh.mutextAlarmManagerFlag.Unlock()
3185}
3186
Himani Chawla1472c682021-03-17 17:11:14 +05303187func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303188 dh.mutextAlarmManagerFlag.RLock()
3189 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303190 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303191 dh.mutextAlarmManagerFlag.RUnlock()
3192 return flagValue
3193}
3194
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303195func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3196 logger.Debugf(ctx, "startingAlarmManager")
3197
3198 // Start routine to process OMCI GET Responses
3199 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303200 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303201 if stop := <-dh.stopAlarmManager; stop {
3202 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303203 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303204 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303205 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3206 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3207 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303208 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303209 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303210 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3211 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303212 }
3213}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003214
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003215func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
3216 logger.Debugw(ctx, "start reconciling", log.Fields{"withOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
3217
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003218 if !dh.isReconciling() {
3219 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003220 logger.Debugw(ctx, "wait for channel signal or timeout",
3221 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003222 select {
3223 case <-dh.chReconcilingFinished:
3224 logger.Debugw(ctx, "reconciling has been finished in time",
3225 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003226 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003227 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3228 log.Fields{"device-id": dh.deviceID})
3229 }
3230 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003231 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003232 dh.mutexReconcilingFlag.Unlock()
3233 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003234 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003235 dh.mutexReconcilingFlag.Lock()
3236 if skipOnuConfig {
3237 dh.reconciling = cSkipOnuConfigReconciling
3238 } else {
3239 dh.reconciling = cOnuConfigReconciling
3240 }
3241 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003242}
3243
3244func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3245 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3246 if dh.isReconciling() {
3247 dh.chReconcilingFinished <- true
3248 } else {
3249 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3250 }
3251}
3252
3253func (dh *deviceHandler) isReconciling() bool {
3254 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003255 defer dh.mutexReconcilingFlag.RUnlock()
3256 return dh.reconciling != cNoReconciling
3257}
3258
3259func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3260 dh.mutexReconcilingFlag.RLock()
3261 defer dh.mutexReconcilingFlag.RUnlock()
3262 return dh.reconciling == cSkipOnuConfigReconciling
3263}
3264
3265func (dh *deviceHandler) setDeviceReason(value uint8) {
3266 dh.mutexDeviceReason.Lock()
3267 dh.deviceReason = value
3268 dh.mutexDeviceReason.Unlock()
3269}
3270
3271func (dh *deviceHandler) getDeviceReason() uint8 {
3272 dh.mutexDeviceReason.RLock()
3273 value := dh.deviceReason
3274 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003275 return value
3276}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003277
3278func (dh *deviceHandler) getDeviceReasonString() string {
3279 return deviceReasonMap[dh.getDeviceReason()]
3280}