blob: 46c2b4a4e3a5c0503b43716a15b48ef1f52ee945 [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 {
mpagenko6d4072a2021-04-09 15:17:10 +00001691 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
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
mpagenko6d4072a2021-04-09 15:17:10 +00001704 pVlanFilterFsm.CancelProcessing(ctx)
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 Hildebrandt0f5449f2021-05-20 10:54:33 +00002164 return //TODO with VOL-3045: rw-core is unresponsive: report error and/or perform self-initiated onu-reset?)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002165 }
2166 oltSerialNumber := parentDevice.SerialNumber
2167
2168 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2169 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2170 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302171 eventContext["olt-serial-number"] = oltSerialNumber
2172 eventContext["device-id"] = aDeviceID
2173 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002174 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002175 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002176
2177 /* Populating device event body */
2178 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302179 de.ResourceId = aDeviceID
2180 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002181 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2182 de.Description = fmt.Sprintf("%s Event - %s - %s",
2183 cEventObjectType, cOnuActivatedEvent, "Raised")
2184 } else {
2185 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2186 de.Description = fmt.Sprintf("%s Event - %s - %s",
2187 cEventObjectType, cOnuActivatedEvent, "Cleared")
2188 }
2189 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2191 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302192 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002193 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302195 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002196}
2197
Himani Chawla4d908332020-08-31 12:30:20 +05302198// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002199func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002200 chLSFsm := make(chan Message, 2048)
2201 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302202 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002204 sFsmName = "LockStateFSM"
2205 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002207 sFsmName = "UnLockStateFSM"
2208 }
mpagenko3af1f032020-06-10 08:53:41 +00002209
dbainbri4d3a0dc2020-12-02 00:33:42 +00002210 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002211 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002213 return
2214 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002216 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002217 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302218 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002219 dh.pLockStateFsm = pLSFsm
2220 } else {
2221 dh.pUnlockStateFsm = pLSFsm
2222 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002224 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002226 }
2227}
2228
2229// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002230func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002231 /* Uni Port lock/unlock procedure -
2232 ***** should run via 'adminDone' state and generate the argument requested event *****
2233 */
2234 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302235 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002236 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2237 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2238 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002239 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302240 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002241 }
2242 } else {
2243 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2244 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2245 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002246 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302247 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002248 }
2249 }
2250 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002251 if pLSStatemachine.Is(uniStDisabled) {
2252 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002254 // maybe try a FSM reset and then again ... - TODO!!!
2255 } else {
2256 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002257 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002258 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002259 }
2260 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002262 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002263 // maybe try a FSM reset and then again ... - TODO!!!
2264 }
2265 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002267 // maybe try a FSM reset and then again ... - TODO!!!
2268 }
2269}
2270
mpagenko80622a52021-02-09 16:53:23 +00002271// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002272func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002273 //in here lockUpgradeFsm is already locked
2274 chUpgradeFsm := make(chan Message, 2048)
2275 var sFsmName = "OnuSwUpgradeFSM"
2276 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002277 if apDevEntry.PDevOmciCC == nil {
2278 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2279 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002280 }
mpagenko15ff4a52021-03-02 10:09:20 +00002281 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002282 sFsmName, chUpgradeFsm)
2283 if dh.pOnuUpradeFsm != nil {
2284 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2285 if pUpgradeStatemachine != nil {
2286 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2287 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2288 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2289 // maybe try a FSM reset and then again ... - TODO!!!
2290 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2291 }
2292 /***** LockStateFSM started */
2293 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2294 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2295 } else {
2296 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2297 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2298 // maybe try a FSM reset and then again ... - TODO!!!
2299 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2300 }
2301 } else {
2302 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2303 // maybe try a FSM reset and then again ... - TODO!!!
2304 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2305 }
2306 } else {
2307 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2308 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2309 }
2310 return nil
2311}
2312
2313// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2314func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2315 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2316 "device-id": dh.deviceID})
2317 dh.lockUpgradeFsm.Lock()
2318 defer dh.lockUpgradeFsm.Unlock()
2319 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2320}
2321
mpagenko15ff4a52021-03-02 10:09:20 +00002322// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2323func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2324 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2325 if pDevEntry == nil {
2326 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2327 return
2328 }
2329
2330 dh.lockUpgradeFsm.RLock()
2331 defer dh.lockUpgradeFsm.RUnlock()
2332 if dh.pOnuUpradeFsm != nil {
2333 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2334 if pUpgradeStatemachine != nil {
2335 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2336 // (some manual forced commit could do without)
2337 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002338 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002339 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2340 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2341 return
2342 }
2343 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2344 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2345 } else {
2346 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2347 log.Fields{"device-id": dh.deviceID})
2348 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2349 return
2350 }
2351 }
2352 }
2353 } else {
2354 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2355 }
2356}
2357
Himani Chawla6d2ae152020-09-02 13:11:20 +05302358//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002359func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002360
2361 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002362 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002363 kvbackend := &db.Backend{
2364 Client: dh.pOpenOnuAc.kvClient,
2365 StoreType: dh.pOpenOnuAc.KVStoreType,
2366 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002367 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002368 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2369 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002370
mpagenkoaf801632020-07-03 10:00:42 +00002371 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002372}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002373func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002375
mpagenkodff5dda2020-08-28 11:52:01 +00002376 for _, field := range flow.GetOfbFields(apFlowItem) {
2377 switch field.Type {
2378 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2379 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002381 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2382 }
mpagenko01e726e2020-10-23 09:45:29 +00002383 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002384 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2385 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302386 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002387 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302388 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2389 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002390 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2391 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002392 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2393 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302394 return
mpagenkodff5dda2020-08-28 11:52:01 +00002395 }
2396 }
mpagenko01e726e2020-10-23 09:45:29 +00002397 */
mpagenkodff5dda2020-08-28 11:52:01 +00002398 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2399 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302400 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002401 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302402 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002403 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302404 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002405 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002406 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302407 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002408 }
2409 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2410 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302411 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002413 "PCP": loAddPcp})
2414 }
2415 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2416 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002418 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2419 }
2420 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2421 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002422 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002423 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2424 }
2425 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2426 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002427 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002428 "IPv4-DST": field.GetIpv4Dst()})
2429 }
2430 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2431 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002433 "IPv4-SRC": field.GetIpv4Src()})
2434 }
2435 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2436 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002437 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002438 "Metadata": field.GetTableMetadata()})
2439 }
2440 /*
2441 default:
2442 {
2443 //all other entires ignored
2444 }
2445 */
2446 }
2447 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302448}
mpagenkodff5dda2020-08-28 11:52:01 +00002449
dbainbri4d3a0dc2020-12-02 00:33:42 +00002450func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002451 for _, action := range flow.GetActions(apFlowItem) {
2452 switch action.Type {
2453 /* not used:
2454 case of.OfpActionType_OFPAT_OUTPUT:
2455 {
mpagenko01e726e2020-10-23 09:45:29 +00002456 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002457 "Output": action.GetOutput()})
2458 }
2459 */
2460 case of.OfpActionType_OFPAT_PUSH_VLAN:
2461 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002462 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002463 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2464 }
2465 case of.OfpActionType_OFPAT_SET_FIELD:
2466 {
2467 pActionSetField := action.GetSetField()
2468 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002469 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002470 "OxcmClass": pActionSetField.Field.OxmClass})
2471 }
2472 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302473 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002474 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302475 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002476 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302477 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002478 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302479 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002480 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002482 "Type": pActionSetField.Field.GetOfbField().Type})
2483 }
2484 }
2485 /*
2486 default:
2487 {
2488 //all other entires ignored
2489 }
2490 */
2491 }
2492 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302493}
2494
2495//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302497 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2498 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2499 var loAddPcp, loSetPcp uint8
2500 var loIPProto uint32
2501 /* the TechProfileId is part of the flow Metadata - compare also comment within
2502 * OLT-Adapter:openolt_flowmgr.go
2503 * Metadata 8 bytes:
2504 * Most Significant 2 Bytes = Inner VLAN
2505 * Next 2 Bytes = Tech Profile ID(TPID)
2506 * Least Significant 4 Bytes = Port ID
2507 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2508 * subscriber related flows.
2509 */
2510
dbainbri4d3a0dc2020-12-02 00:33:42 +00002511 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302512 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002513 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302514 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002515 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302516 }
mpagenko551a4d42020-12-08 18:09:20 +00002517 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002518 loCookie := apFlowItem.GetCookie()
2519 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002521 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302522
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002524 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302525 if loIPProto == 2 {
2526 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2527 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002528 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2529 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302530 return nil
2531 }
mpagenko01e726e2020-10-23 09:45:29 +00002532 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002534
2535 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002537 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2538 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2539 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2540 //TODO!!: Use DeviceId within the error response to rwCore
2541 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002542 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002543 }
2544 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002546 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2547 } else {
2548 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2549 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2550 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302551 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002552 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002554 }
mpagenko9a304ea2020-12-16 15:54:01 +00002555
2556 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002557 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002558 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302559 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002560 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002561 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002562 dh.lockVlanConfig.RUnlock()
2563 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002564 }
mpagenkof1fc3862021-02-16 10:09:52 +00002565 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002567 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002568}
2569
2570//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002572 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2573 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2574 //no extra check is done on the rule parameters
2575 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2576 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2577 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2578 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002579 // - 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 +00002580 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002581 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002582
2583 /* TT related temporary workaround - should not be needed anymore
2584 for _, field := range flow.GetOfbFields(apFlowItem) {
2585 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2586 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002587 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002588 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2589 if loIPProto == 2 {
2590 // 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 +00002591 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002592 log.Fields{"device-id": dh.deviceID})
2593 return nil
2594 }
2595 }
2596 } //for all OfbFields
2597 */
2598
mpagenko9a304ea2020-12-16 15:54:01 +00002599 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002600 dh.lockVlanConfig.RLock()
2601 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002602 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002603 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002604 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002606 log.Fields{"device-id": dh.deviceID})
2607 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002608 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002610
mpagenko01e726e2020-10-23 09:45:29 +00002611 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002612}
2613
Himani Chawla26e555c2020-08-31 12:30:20 +05302614// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002615// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002616func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002617 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002618 chVlanFilterFsm := make(chan Message, 2048)
2619
dbainbri4d3a0dc2020-12-02 00:33:42 +00002620 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002621 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302623 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002624 }
2625
dbainbri4d3a0dc2020-12-02 00:33:42 +00002626 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002627 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2628 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002629 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002630 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002631 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2632 // (from parallel processing)
2633 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302634 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002635 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2636 if pVlanFilterStatemachine != nil {
2637 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2638 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002639 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302640 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002641 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302642 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302644 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2645 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002646 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002647 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002648 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302649 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002650 }
2651 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002652 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002653 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302654 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002655 }
2656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002657 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002658 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302659 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002660 }
2661 return nil
2662}
2663
mpagenkofc4f56e2020-11-04 17:17:49 +00002664//VerifyVlanConfigRequest checks on existence of a given uniPort
2665// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002666func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002667 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2668 var pCurrentUniPort *onuUniPort
2669 for _, uniPort := range dh.uniEntityMap {
2670 // only if this port is validated for operState transfer
2671 if uniPort.uniID == uint8(aUniID) {
2672 pCurrentUniPort = uniPort
2673 break //found - end search loop
2674 }
2675 }
2676 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002677 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002678 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2679 return
2680 }
mpagenko551a4d42020-12-08 18:09:20 +00002681 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002682}
2683
mpagenkodff5dda2020-08-28 11:52:01 +00002684//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002685func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002686 //TODO!! verify and start pending flow configuration
2687 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2688 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002689
2690 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302691 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002692 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002693 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2694 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2695 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002696 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2697 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2698 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2699 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2700 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2701 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2702 } else {
2703 /***** UniVlanConfigFsm continued */
2704 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2705 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2706 "UniPort": apUniPort.portNo})
2707 }
2708 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2709 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2710 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2711 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2712 } else {
2713 /***** UniVlanConfigFsm continued */
2714 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2715 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2716 "UniPort": apUniPort.portNo})
2717 }
mpagenkodff5dda2020-08-28 11:52:01 +00002718 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002719 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2720 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002721 "UniPort": apUniPort.portNo})
2722 }
2723 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002724 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2725 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2726 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002727 }
2728 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002729 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002730 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002731 }
mpagenkof1fc3862021-02-16 10:09:52 +00002732 } else {
2733 dh.lockVlanConfig.RUnlock()
2734 }
mpagenkodff5dda2020-08-28 11:52:01 +00002735}
2736
2737//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2738// 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 +00002739func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2740 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002741 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2742 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002743 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302744 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002745 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002746}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002747
Girish Gowdra26a40922021-01-29 17:14:34 -08002748//ProcessPendingTpDelete processes any pending TP delete (if available)
2749func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2750 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2751 if apUniPort == nil {
2752 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2753 return
2754 }
2755 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2756 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2757 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2758 if pAniConfigStatemachine != nil {
2759 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2760 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2761 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2762 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2763 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2764 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2765 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2766 return
2767 }
2768 } else {
2769 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2770 return
2771 }
2772 }
2773 return
2774 }
2775}
2776
mpagenkof1fc3862021-02-16 10:09:52 +00002777//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2778func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2779 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2780 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2781 // obviously then parallel processing on the cancel must be avoided
2782 // deadline context to ensure completion of background routines waited for
2783 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2784 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2785 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2786
2787 aPDevEntry.resetKvProcessingErrorIndication()
2788 var wg sync.WaitGroup
2789 wg.Add(1) // for the 1 go routine to finish
2790
2791 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2792 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2793
2794 return aPDevEntry.getKvProcessingErrorIndication()
2795}
2796
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002797//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2798//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002799func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2800 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002801
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002802 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002803 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002804 return nil
2805 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002806 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002807
dbainbri4d3a0dc2020-12-02 00:33:42 +00002808 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002809 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002810 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002811 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2812 }
2813 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2814
mpagenkof1fc3862021-02-16 10:09:52 +00002815 if aWriteToKvStore {
2816 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2817 }
2818 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002819}
2820
dbainbri4d3a0dc2020-12-02 00:33:42 +00002821func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002822 defer cancel() //ensure termination of context (may be pro forma)
2823 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002824 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002825 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002826}
2827
dbainbri4d3a0dc2020-12-02 00:33:42 +00002828func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002829
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002830 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002831 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002832 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002833 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2834 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002835 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002836 return err
2837 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002838 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002839 return nil
2840 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002842 return nil
2843}
2844
dbainbri4d3a0dc2020-12-02 00:33:42 +00002845func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2846 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002847 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002848 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002849 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2850 }
mpagenkof1fc3862021-02-16 10:09:52 +00002851 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002852}
2853
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002854func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2855 var errStr string = ""
2856 for _, err := range errS {
2857 if err != nil {
2858 errStr = errStr + err.Error() + " "
2859 }
2860 }
2861 if errStr != "" {
2862 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2863 }
2864 return nil
2865}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002866
2867// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2868func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2869 dh.lockDevice.RLock()
2870 defer dh.lockDevice.RUnlock()
2871 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2872 return uniPort.entityID, nil
2873 }
2874 return 0, errors.New("error-fetching-uni-port")
2875}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002876
2877// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002878func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2879 var errorsList []error
2880 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 -08002881
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002882 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2883 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2884 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2885
2886 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2887 // successfully.
2888 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2889 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2890 if len(errorsList) > 0 {
2891 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2892 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002893 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002894 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2895 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002896}
2897
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002898func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2899 var err error
2900 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002901 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002902
2903 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2904 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2905 errorsList = append(errorsList, err)
2906 }
2907 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002908 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002909
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002910 return errorsList
2911}
2912
2913func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2914 var err error
2915 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002916 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002917 // Check if group metric related config is updated
2918 for _, v := range pmConfigs.Groups {
2919 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2920 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2921 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2922
2923 if ok && m.frequency != v.GroupFreq {
2924 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2925 errorsList = append(errorsList, err)
2926 }
2927 }
2928 if ok && m.enabled != v.Enabled {
2929 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2930 errorsList = append(errorsList, err)
2931 }
2932 }
2933 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002934 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002935 return errorsList
2936}
2937
2938func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2939 var err error
2940 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002941 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002942 // Check if standalone metric related config is updated
2943 for _, v := range pmConfigs.Metrics {
2944 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002945 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002946 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2947
2948 if ok && m.frequency != v.SampleFreq {
2949 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2950 errorsList = append(errorsList, err)
2951 }
2952 }
2953 if ok && m.enabled != v.Enabled {
2954 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2955 errorsList = append(errorsList, err)
2956 }
2957 }
2958 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002959 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002960 return errorsList
2961}
2962
2963// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002964func (dh *deviceHandler) startCollector(ctx context.Context) {
2965 logger.Debugf(ctx, "startingCollector")
2966
2967 // Start routine to process OMCI GET Responses
2968 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002969 // Initialize the next metric collection time.
2970 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2971 // reset like onu rebooted.
2972 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002973 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002974 for {
2975 select {
2976 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002977 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002978 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002979 // Stop the L2 PM FSM
2980 go func() {
2981 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2982 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2983 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2984 }
2985 } else {
2986 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2987 }
2988 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002989 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2990 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2991 }
2992 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2993 dh.pOnuMetricsMgr.stopTicks <- true
2994 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002995
Girish Gowdrae09a6202021-01-12 18:10:59 -08002996 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002997 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2998 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2999 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3000 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3001 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003002 // Update the next metric collection time.
3003 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003004 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003005 } else {
3006 if dh.pmConfigs.Grouped { // metrics are managed as a group
3007 // parse through the group and standalone metrics to see it is time to collect their metrics
3008 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003009
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003010 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3011 // 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 -08003012 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3013 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003014 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3015 }
3016 }
3017 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3018 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3019 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3020 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3021 }
3022 }
3023 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3024
3025 // parse through the group and update the next metric collection time
3026 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3027 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3028 // 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 -08003029 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3030 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003031 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3032 }
3033 }
3034 // parse through the standalone metrics and update the next metric collection time
3035 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3036 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3037 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3038 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3039 }
3040 }
3041 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3042 } /* else { // metrics are not managed as a group
3043 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3044 } */
3045 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003046 }
3047 }
3048}
kesavandfdf77632021-01-26 23:40:33 -05003049
3050func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3051
3052 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3053 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3054}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003055
mpagenkof1fc3862021-02-16 10:09:52 +00003056func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3057 if pFsm == nil {
3058 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003059 }
mpagenkof1fc3862021-02-16 10:09:52 +00003060 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003061}
3062
mpagenkof1fc3862021-02-16 10:09:52 +00003063func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3064 var pFsm *fsm.FSM
3065 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3066 switch omciFsm {
3067 case cUploadFsm:
3068 {
3069 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3070 }
3071 case cDownloadFsm:
3072 {
3073 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3074 }
3075 case cUniLockFsm:
3076 {
3077 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3078 }
3079 case cUniUnLockFsm:
3080 {
3081 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3082 }
3083 case cL2PmFsm:
3084 {
3085 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3086 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3087 } else {
3088 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003089 }
3090 }
mpagenko80622a52021-02-09 16:53:23 +00003091 case cOnuUpgradeFsm:
3092 {
3093 dh.lockUpgradeFsm.RLock()
3094 defer dh.lockUpgradeFsm.RUnlock()
3095 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3096 }
mpagenkof1fc3862021-02-16 10:09:52 +00003097 default:
3098 {
3099 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3100 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3101 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003102 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003103 }
mpagenkof1fc3862021-02-16 10:09:52 +00003104 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003105}
3106
mpagenkof1fc3862021-02-16 10:09:52 +00003107func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3108 for _, v := range dh.pOnuTP.pAniConfigFsm {
3109 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003110 return false
3111 }
3112 }
3113 return true
3114}
3115
mpagenkof1fc3862021-02-16 10:09:52 +00003116func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3117 dh.lockVlanConfig.RLock()
3118 defer dh.lockVlanConfig.RUnlock()
3119 for _, v := range dh.UniVlanConfigFsmMap {
3120 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3121 return false
3122 }
3123 }
3124 return true //FSM not active - so there is no activity on omci
3125}
3126
3127func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3128 dh.lockVlanConfig.RLock()
3129 defer dh.lockVlanConfig.RUnlock()
3130 for _, v := range dh.UniVlanConfigFsmMap {
3131 if v.pAdaptFsm.pFsm != nil {
3132 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3133 return true //there is at least one VLAN FSM with some active configuration
3134 }
3135 }
3136 }
3137 return false //there is no VLAN FSM with some active configuration
3138}
3139
3140func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3141 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3142 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3143 return false
3144 }
3145 }
3146 // a further check is done to identify, if at least some data traffic related configuration exists
3147 // 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])
3148 return dh.checkUserServiceExists(ctx)
3149}
3150
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003151func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3152 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3153 if err := dh.resetFsms(ctx, false); err != nil {
3154 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3155 // TODO: fatal error reset ONU, delete deviceHandler!
3156 return
3157 }
3158 if !dh.getCollectorIsRunning() {
3159 // Start PM collector routine
3160 go dh.startCollector(ctx)
3161 }
Himani Chawla1472c682021-03-17 17:11:14 +05303162 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303163 go dh.startAlarmManager(ctx)
3164 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003165 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003166 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003167}
3168
3169func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3170 dh.mutexCollectorFlag.Lock()
3171 dh.collectorIsRunning = flagValue
3172 dh.mutexCollectorFlag.Unlock()
3173}
3174
3175func (dh *deviceHandler) getCollectorIsRunning() bool {
3176 dh.mutexCollectorFlag.RLock()
3177 flagValue := dh.collectorIsRunning
3178 dh.mutexCollectorFlag.RUnlock()
3179 return flagValue
3180}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303181
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303182func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3183 dh.mutextAlarmManagerFlag.Lock()
3184 dh.alarmManagerIsRunning = flagValue
3185 dh.mutextAlarmManagerFlag.Unlock()
3186}
3187
Himani Chawla1472c682021-03-17 17:11:14 +05303188func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303189 dh.mutextAlarmManagerFlag.RLock()
3190 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303191 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303192 dh.mutextAlarmManagerFlag.RUnlock()
3193 return flagValue
3194}
3195
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303196func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3197 logger.Debugf(ctx, "startingAlarmManager")
3198
3199 // Start routine to process OMCI GET Responses
3200 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303201 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303202 if stop := <-dh.stopAlarmManager; stop {
3203 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303204 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303205 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303206 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3207 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3208 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303209 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303210 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303211 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3212 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303213 }
3214}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003215
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003216func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
3217 logger.Debugw(ctx, "start reconciling", log.Fields{"withOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
3218
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003219 if !dh.isReconciling() {
3220 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003221 logger.Debugw(ctx, "wait for channel signal or timeout",
3222 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003223 select {
3224 case <-dh.chReconcilingFinished:
3225 logger.Debugw(ctx, "reconciling has been finished in time",
3226 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003227 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003228 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3229 log.Fields{"device-id": dh.deviceID})
3230 }
3231 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003232 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003233 dh.mutexReconcilingFlag.Unlock()
3234 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003235 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003236 dh.mutexReconcilingFlag.Lock()
3237 if skipOnuConfig {
3238 dh.reconciling = cSkipOnuConfigReconciling
3239 } else {
3240 dh.reconciling = cOnuConfigReconciling
3241 }
3242 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003243}
3244
3245func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3246 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3247 if dh.isReconciling() {
3248 dh.chReconcilingFinished <- true
3249 } else {
3250 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3251 }
3252}
3253
3254func (dh *deviceHandler) isReconciling() bool {
3255 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003256 defer dh.mutexReconcilingFlag.RUnlock()
3257 return dh.reconciling != cNoReconciling
3258}
3259
3260func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3261 dh.mutexReconcilingFlag.RLock()
3262 defer dh.mutexReconcilingFlag.RUnlock()
3263 return dh.reconciling == cSkipOnuConfigReconciling
3264}
3265
3266func (dh *deviceHandler) setDeviceReason(value uint8) {
3267 dh.mutexDeviceReason.Lock()
3268 dh.deviceReason = value
3269 dh.mutexDeviceReason.Unlock()
3270}
3271
3272func (dh *deviceHandler) getDeviceReason() uint8 {
3273 dh.mutexDeviceReason.RLock()
3274 value := dh.deviceReason
3275 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003276 return value
3277}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003278
3279func (dh *deviceHandler) getDeviceReasonString() string {
3280 return deviceReasonMap[dh.getDeviceReason()]
3281}