blob: ac04031deed4b8601b12094fb74ddd5477f1728a [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 Hildebrandtbe523842021-03-10 10:47:18 +0000813 dh.stopReconciling(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000814 return
815 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 dh.pOnuTP.lockTpProcMutex()
817 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000818 pDevEntry.persUniConfigMutex.RLock()
819 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000820
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000821 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000823 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000824 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000825 return
826 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000827 techProfsFound := false
828 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000829 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000830 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
831 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000832 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000833 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000834 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000836 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800837 for tpID := range uniData.PersTpPathMap {
838 // deadline context to ensure completion of background routines waited for
839 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
840 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000842
Girish Gowdra041dcb32020-11-16 16:54:30 -0800843 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
844 var wg sync.WaitGroup
845 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
847 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800848 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800850 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000851 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000852 if len(uniData.PersFlowParams) != 0 {
853 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000856 if !techProfsFound {
857 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
858 log.Fields{"device-id": dh.deviceID})
859 dh.stopReconciling(ctx)
860 return
861 }
862 if dh.isSkipOnuConfigReconciling() {
863 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
864 }
865 if !flowsFound {
866 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
867 log.Fields{"device-id": dh.deviceID})
868 dh.stopReconciling(ctx)
869 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870}
871
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
873 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000878 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000879 return
880 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000881 pDevEntry.persUniConfigMutex.RLock()
882 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000883
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000884 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000886 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000887 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000888 return
889 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000890 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000891 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000892 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
893 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000894 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000895 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000896 continue
897 }
898 if len(uniData.PersTpPathMap) == 0 {
899 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
900 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000901 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000902 var uniPort *onuUniPort
903 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000904 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000906 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
907 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
908 dh.stopReconciling(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909 return
910 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000911 flowsFound = true
912 flowsProcessed := 0
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000913 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000914 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000915 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000916 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000917 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000919 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
920 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000921 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922 }
mpagenkof1fc3862021-02-16 10:09:52 +0000923 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000924 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000925 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000927 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000928 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000930 }
931 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000932 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000933 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000934 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
935 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
936 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
937 }
938 if !flowsFound {
939 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
940 log.Fields{"device-id": dh.deviceID})
941 dh.stopReconciling(ctx)
942 return
943 }
944 if dh.isSkipOnuConfigReconciling() {
945 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000946 }
947}
948
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
950 logger.Debugw(ctx, "reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000951
952 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000953 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000954}
955
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
957 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000958
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000960 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000961 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000962 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000963 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000964 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000965
966 // deadline context to ensure completion of background routines waited for
967 //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 +0530968 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000970
971 pDevEntry.resetKvProcessingErrorIndication()
972
973 var wg sync.WaitGroup
974 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
976 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000977
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000978 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000979 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000980}
981
mpagenko15ff4a52021-03-02 10:09:20 +0000982//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
983// before this change here return like this was used:
984// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
985//was and is called in background - error return does not make sense
986func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
987 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
988 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +0000990 return
ozgecanetsiae11479f2020-07-06 09:44:47 +0300991 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530993 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +0000995 return
Himani Chawla4d908332020-08-31 12:30:20 +0530996 }
mpagenko01e726e2020-10-23 09:45:29 +0000997
998 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001000
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001002 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001003 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001004 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001005 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001007 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001008 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001010 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001011 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001012 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +00001013 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1014 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1015 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1016 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001017}
1018
mpagenkoc8bba412021-01-15 15:38:44 +00001019//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001020func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1021 apDownloadManager *adapterDownloadManager) error {
1022 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001023 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001024
1025 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001026 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1027 if pDevEntry == nil {
1028 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1029 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1030 }
1031
mpagenko80622a52021-02-09 16:53:23 +00001032 if dh.ReadyForSpecificOmciConfig {
mpagenko15ff4a52021-03-02 10:09:20 +00001033 var inactiveImageID uint16
1034 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1035 dh.lockUpgradeFsm.Lock()
1036 defer dh.lockUpgradeFsm.Unlock()
1037 if dh.pOnuUpradeFsm == nil {
1038 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1039 if err == nil {
1040 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1041 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1042 "device-id": dh.deviceID, "error": err})
1043 }
1044 } else {
1045 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001046 "device-id": dh.deviceID, "error": err})
1047 }
mpagenko15ff4a52021-03-02 10:09:20 +00001048 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1049 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1050 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1051 if pUpgradeStatemachine != nil {
1052 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1053 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1054 "device-id": dh.deviceID, "error": err})
1055 }
1056 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1057 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1058 // for now a second start of download should work again
1059 } else { //should never occur
1060 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1061 "device-id": dh.deviceID})
1062 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001063 }
mpagenko80622a52021-02-09 16:53:23 +00001064 }
mpagenko15ff4a52021-03-02 10:09:20 +00001065 } else {
1066 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1067 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001068 }
1069 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001070 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1071 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001072 }
1073 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001074}
1075
Himani Chawla6d2ae152020-09-02 13:11:20 +05301076// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001077// #####################################################################################
1078
1079// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301080// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001081
dbainbri4d3a0dc2020-12-02 00:33:42 +00001082func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1083 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 +00001084}
1085
1086// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001087func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001088
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090 var err error
1091
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001092 // populate what we know. rest comes later after mib sync
1093 dh.device.Root = false
1094 dh.device.Vendor = "OpenONU"
1095 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001096 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001097 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001098
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001099 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001100
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001101 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1103 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301104 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001105 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001106 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001107 log.Fields{"device-id": dh.deviceID})
1108 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001109
Himani Chawla4d908332020-08-31 12:30:20 +05301110 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001111 dh.ponPortNumber = dh.device.ParentPortNo
1112
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001113 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1114 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1115 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001117 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301118 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119
1120 /*
1121 self._pon = PonPort.create(self, self._pon_port_number)
1122 self._pon.add_peer(self.parent_id, self._pon_port_number)
1123 self.logger.debug('adding-pon-port-to-agent',
1124 type=self._pon.get_port().type,
1125 admin_state=self._pon.get_port().admin_state,
1126 oper_status=self._pon.get_port().oper_status,
1127 )
1128 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001129 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001131 var ponPortNo uint32 = 1
1132 if dh.ponPortNumber != 0 {
1133 ponPortNo = dh.ponPortNumber
1134 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001136 pPonPort := &voltha.Port{
1137 PortNo: ponPortNo,
1138 Label: fmt.Sprintf("pon-%d", ponPortNo),
1139 Type: voltha.Port_PON_ONU,
1140 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301141 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001142 PortNo: ponPortNo}}, // Peer port is parent's port number
1143 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1145 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001146 e.Cancel(err)
1147 return
1148 }
1149 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001150 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001151 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001153}
1154
1155// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001157
dbainbri4d3a0dc2020-12-02 00:33:42 +00001158 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001159 var err error
1160 /*
1161 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1162 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1163 return nil
1164 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1166 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001167 e.Cancel(err)
1168 return
1169 }
1170
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001171 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001173 // reconcilement will be continued after mib download is done
1174 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001175
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176 /*
1177 ############################################################################
1178 # Setup Alarm handler
1179 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1180 device.serial_number)
1181 ############################################################################
1182 # Setup PM configuration for this device
1183 # Pass in ONU specific options
1184 kwargs = {
1185 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1186 'heartbeat': self.heartbeat,
1187 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1188 }
1189 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1190 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1191 self.logical_device_id, device.serial_number,
1192 grouped=True, freq_override=False, **kwargs)
1193 pm_config = self._pm_metrics.make_proto()
1194 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1195 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1196 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1197
1198 # Note, ONU ID and UNI intf set in add_uni_port method
1199 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1200 ani_ports=[self._pon])
1201
1202 # Code to Run OMCI Test Action
1203 kwargs_omci_test_action = {
1204 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1205 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1206 }
1207 serial_number = device.serial_number
1208 self._test_request = OmciTestRequest(self.core_proxy,
1209 self.omci_agent, self.device_id,
1210 AniG, serial_number,
1211 self.logical_device_id,
1212 exclusive=False,
1213 **kwargs_omci_test_action)
1214
1215 self.enabled = True
1216 else:
1217 self.logger.info('onu-already-activated')
1218 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001219
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001221}
1222
1223// doStateConnected get the device info and update to voltha core
1224// for comparison of the original method (not that easy to uncomment): compare here:
1225// voltha-openolt-adapter/adaptercore/device_handler.go
1226// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001227func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001228
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301230 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001231 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001232 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001233}
1234
1235// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001237
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301239 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001240 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001241 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001242
1243 /*
1244 // Synchronous call to update device state - this method is run in its own go routine
1245 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1246 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001247 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 +00001248 return err
1249 }
1250 return nil
1251 */
1252}
1253
1254// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001256
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001258 var err error
1259
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001260 device := dh.device
1261 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001262 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001264 e.Cancel(err)
1265 return
1266 }
1267
1268 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001270 /*
1271 // Update the all ports state on that device to disable
1272 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001273 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001274 return er
1275 }
1276
1277 //Update the device oper state and connection status
1278 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1279 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1280 dh.device = cloned
1281
1282 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001283 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001284 return er
1285 }
1286
1287 //get the child device for the parent device
1288 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1289 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001290 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001291 return err
1292 }
1293 for _, onuDevice := range onuDevices.Items {
1294
1295 // Update onu state as down in onu adapter
1296 onuInd := oop.OnuIndication{}
1297 onuInd.OperState = "down"
1298 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1299 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1300 if er != nil {
1301 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001302 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001303 //Do not return here and continue to process other ONUs
1304 }
1305 }
1306 // * Discovered ONUs entries need to be cleared , since after OLT
1307 // is up, it starts sending discovery indications again* /
1308 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001309 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001310 return nil
1311 */
Himani Chawla4d908332020-08-31 12:30:20 +05301312 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001313 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001315}
1316
Himani Chawla6d2ae152020-09-02 13:11:20 +05301317// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001318// #################################################################################
1319
1320// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301321// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001322
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001323//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001325 dh.lockDevice.RLock()
1326 pOnuDeviceEntry := dh.pOnuOmciDevice
1327 if aWait && pOnuDeviceEntry == nil {
1328 //keep the read sema short to allow for subsequent write
1329 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001330 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001331 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1332 // so it might be needed to wait here for that event with some timeout
1333 select {
1334 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001335 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001336 return nil
1337 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001338 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001339 // if written now, we can return the written value without sema
1340 return dh.pOnuOmciDevice
1341 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342 }
mpagenko3af1f032020-06-10 08:53:41 +00001343 dh.lockDevice.RUnlock()
1344 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001345}
1346
Himani Chawla6d2ae152020-09-02 13:11:20 +05301347//setOnuDeviceEntry sets the ONU device entry within the handler
1348func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301349 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001350 dh.lockDevice.Lock()
1351 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001352 dh.pOnuOmciDevice = apDeviceEntry
1353 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001354 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301355 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001356}
1357
Himani Chawla6d2ae152020-09-02 13:11:20 +05301358//addOnuDeviceEntry creates a new ONU device or returns the existing
1359func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001360 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001361
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001363 if deviceEntry == nil {
1364 /* costum_me_map in python code seems always to be None,
1365 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1366 /* also no 'clock' argument - usage open ...*/
1367 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001368 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001369 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001370 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301371 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001372 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301373 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001374 // fire deviceEntry ready event to spread to possibly waiting processing
1375 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001376 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001377 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001378 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001379 }
1380 // might be updated with some error handling !!!
1381 return nil
1382}
1383
dbainbri4d3a0dc2020-12-02 00:33:42 +00001384func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1385 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001386 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1387
1388 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001389
dbainbri4d3a0dc2020-12-02 00:33:42 +00001390 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001391 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001392 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001393 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1394 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001395 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001396 if err := dh.storePersistentData(ctx); err != nil {
1397 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001398 log.Fields{"device-id": dh.deviceID, "err": err})
1399 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001401 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001402 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001403 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1404 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001405 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001406 }
1407 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001408 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001409 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001410
1411 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001412 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 +00001413 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001414 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001415 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001416 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001417 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1418 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1419 // 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 +00001420 // 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 +00001421 // so let's just try to keep it simple ...
1422 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001424 if err != nil || device == nil {
1425 //TODO: needs to handle error scenarios
1426 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1427 return errors.New("Voltha Device not found")
1428 }
1429 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001430
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001432 return err
mpagenko3af1f032020-06-10 08:53:41 +00001433 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001434
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001435 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001436
1437 /* this might be a good time for Omci Verify message? */
1438 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001440 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001441 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001443
1444 /* give the handler some time here to wait for the OMCi verification result
1445 after Timeout start and try MibUpload FSM anyway
1446 (to prevent stopping on just not supported OMCI verification from ONU) */
1447 select {
1448 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001449 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001450 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 }
1453
1454 /* In py code it looks earlier (on activate ..)
1455 # Code to Run OMCI Test Action
1456 kwargs_omci_test_action = {
1457 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1458 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1459 }
1460 serial_number = device.serial_number
1461 self._test_request = OmciTestRequest(self.core_proxy,
1462 self.omci_agent, self.device_id,
1463 AniG, serial_number,
1464 self.logical_device_id,
1465 exclusive=False,
1466 **kwargs_omci_test_action)
1467 ...
1468 # Start test requests after a brief pause
1469 if not self._test_request_started:
1470 self._test_request_started = True
1471 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1472 reactor.callLater(tststart, self._test_request.start_collector)
1473
1474 */
1475 /* which is then: in omci_test_request.py : */
1476 /*
1477 def start_collector(self, callback=None):
1478 """
1479 Start the collection loop for an adapter if the frequency > 0
1480
1481 :param callback: (callable) Function to call to collect PM data
1482 """
1483 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1484 if callback is None:
1485 callback = self.perform_test_omci
1486
1487 if self.lc is None:
1488 self.lc = LoopingCall(callback)
1489
1490 if self.default_freq > 0:
1491 self.lc.start(interval=self.default_freq / 10)
1492
1493 def perform_test_omci(self):
1494 """
1495 Perform the initial test request
1496 """
1497 ani_g_entities = self._device.configuration.ani_g_entities
1498 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1499 is not None else None
1500 self._entity_id = ani_g_entities_ids[0]
1501 self.logger.info('perform-test', entity_class=self._entity_class,
1502 entity_id=self._entity_id)
1503 try:
1504 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1505 result = yield self._device.omci_cc.send(frame)
1506 if not result.fields['omci_message'].fields['success_code']:
1507 self.logger.info('Self-Test Submitted Successfully',
1508 code=result.fields[
1509 'omci_message'].fields['success_code'])
1510 else:
1511 raise TestFailure('Test Failure: {}'.format(
1512 result.fields['omci_message'].fields['success_code']))
1513 except TimeoutError as e:
1514 self.deferred.errback(failure.Failure(e))
1515
1516 except Exception as e:
1517 self.logger.exception('perform-test-Error', e=e,
1518 class_id=self._entity_class,
1519 entity_id=self._entity_id)
1520 self.deferred.errback(failure.Failure(e))
1521
1522 */
1523
1524 // PM related heartbeat??? !!!TODO....
1525 //self._heartbeat.enabled = True
1526
mpagenko1cc3cb42020-07-27 15:24:38 +00001527 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1528 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1529 * 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 +05301530 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001531 */
1532 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001533 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001534 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001535 if pMibUlFsm.Is(ulStDisabled) {
1536 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 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 +00001538 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301539 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301541 //Determine ONU status and start/re-start MIB Synchronization tasks
1542 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001543 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301544 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 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 +00001546 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001547 }
Himani Chawla4d908332020-08-31 12:30:20 +05301548 } else {
1549 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 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 +00001551 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301552 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001554 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001555 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001557 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001558 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559 }
1560 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001561 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001562 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001563 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001564
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001565 if !dh.getCollectorIsRunning() {
1566 // Start PM collector routine
1567 go dh.startCollector(ctx)
1568 }
Himani Chawla1472c682021-03-17 17:11:14 +05301569 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301570 go dh.startAlarmManager(ctx)
1571 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301572
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573 return nil
1574}
1575
dbainbri4d3a0dc2020-12-02 00:33:42 +00001576func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001577 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001578 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001579 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001580 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001581
mpagenko900ee4b2020-10-12 11:56:34 +00001582 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1583 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1584 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001585 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001587 log.Fields{"device-id": dh.deviceID, "error": err})
1588 // abort: system behavior is just unstable ...
1589 return err
1590 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001591 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 _ = 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 +00001593
1594 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1595 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1596 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001598 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001600 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001601 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001603
1604 //TODO!!! remove existing traffic profiles
1605 /* from py code, if TP's exist, remove them - not yet implemented
1606 self._tp = dict()
1607 # Let TP download happen again
1608 for uni_id in self._tp_service_specific_task:
1609 self._tp_service_specific_task[uni_id].clear()
1610 for uni_id in self._tech_profile_download_done:
1611 self._tech_profile_download_done[uni_id].clear()
1612 */
1613
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001615
mpagenkofc4f56e2020-11-04 17:17:49 +00001616 dh.ReadyForSpecificOmciConfig = false
1617
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001619 // abort: system behavior is just unstable ...
1620 return err
1621 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001623 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001625 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001626 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001627 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001628 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001629 // abort: system behavior is just unstable ...
1630 return err
1631 }
1632 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001634 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635 return nil
1636}
1637
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001638func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001639 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1640 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1641 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1642 // and using the stop/reset event should never harm
1643
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001645 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001647 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1648 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001649 if includingMibSyncFsm {
1650 //the MibSync FSM might be active all the ONU-active time,
1651 // hence it must be stopped unconditionally
1652 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1653 if pMibUlFsm != nil {
1654 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1655 }
mpagenko900ee4b2020-10-12 11:56:34 +00001656 }
1657 //MibDownload may run
1658 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1659 if pMibDlFsm != nil {
1660 _ = pMibDlFsm.Event(dlEvReset)
1661 }
1662 //port lock/unlock FSM's may be active
1663 if dh.pUnlockStateFsm != nil {
1664 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1665 }
1666 if dh.pLockStateFsm != nil {
1667 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1668 }
1669 //techProfile related PonAniConfigFsm FSM may be active
1670 if dh.pOnuTP != nil {
1671 // should always be the case here
1672 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1673 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001674 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko7d6bb022021-03-11 15:07:55 +00001675 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing()
Girish Gowdra041dcb32020-11-16 16:54:30 -08001676 }
mpagenko900ee4b2020-10-12 11:56:34 +00001677 }
1678 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001679 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001680 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001681 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1682 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001683 dh.lockVlanConfig.RUnlock()
1684 //reset of all Fsm is always accompanied by global persistency data removal
1685 // no need to remove specific data
1686 pVlanFilterFsm.RequestClearPersistency(false)
1687 //ensure the FSM processing is stopped in case waiting for some response
1688 pVlanFilterFsm.CancelProcessing()
mpagenkof1fc3862021-02-16 10:09:52 +00001689 } else {
1690 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001691 }
1692 }
1693 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001694 if dh.getCollectorIsRunning() {
1695 // Stop collector routine
1696 dh.stopCollector <- true
1697 }
Himani Chawla1472c682021-03-17 17:11:14 +05301698 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301699 dh.stopAlarmManager <- true
1700 }
1701
mpagenko80622a52021-02-09 16:53:23 +00001702 //reset a possibly running upgrade FSM
1703 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1704 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1705 dh.lockUpgradeFsm.RLock()
1706 if dh.pOnuUpradeFsm != nil {
mpagenko59498c12021-03-18 14:15:15 +00001707 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1708 if pUpgradeStatemachine != nil {
1709 if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
1710 dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
1711 }
1712 _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
1713 }
1714 //else the FSM seems already to be in some released state
mpagenko80622a52021-02-09 16:53:23 +00001715 }
1716 dh.lockUpgradeFsm.RUnlock()
1717
mpagenko7d6bb022021-03-11 15:07:55 +00001718 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001719 return nil
1720}
1721
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1723 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 +05301724
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001725 // store persistent data collected during MIB upload processing
1726 if err := dh.storePersistentData(ctx); err != nil {
1727 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1728 log.Fields{"device-id": dh.deviceID, "err": err})
1729 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001730 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001731 dh.addAllUniPorts(ctx)
1732
mpagenkoa40e99a2020-11-17 13:50:39 +00001733 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1734 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1735 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1736 * disable/enable toggling here to allow traffic
1737 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1738 * like the py comment says:
1739 * # start by locking all the unis till mib sync and initial mib is downloaded
1740 * # this way we can capture the port down/up events when we are ready
1741 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301742
mpagenkoa40e99a2020-11-17 13:50:39 +00001743 // Init Uni Ports to Admin locked state
1744 // *** should generate UniLockStateDone event *****
1745 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001747 } else { //LockStateFSM already init
1748 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001750 }
1751}
1752
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1754 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301755 /* Mib download procedure -
1756 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1757 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001759 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001760 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001761 return
1762 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301763 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1764 if pMibDlFsm != nil {
1765 if pMibDlFsm.Is(dlStDisabled) {
1766 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 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 +05301768 // maybe try a FSM reset and then again ... - TODO!!!
1769 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301771 // maybe use more specific states here for the specific download steps ...
1772 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301774 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301776 //Begin MIB data download (running autonomously)
1777 }
1778 }
1779 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001781 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301782 // maybe try a FSM reset and then again ... - TODO!!!
1783 }
1784 /***** Mib download started */
1785 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301787 }
1788}
1789
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1791 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301792 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001793 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001795 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001796 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1797 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1798 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1799 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301801 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1802 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301804 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301806 }
1807 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301809 log.Fields{"device-id": dh.deviceID})
1810 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001811 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001812
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07001813 if !dh.getCollectorIsRunning() {
1814 // Start PM collector routine
1815 go dh.startCollector(ctx)
1816 }
1817 if !dh.getAlarmManagerIsRunning(ctx) {
1818 go dh.startAlarmManager(ctx)
1819 }
1820
Girish Gowdrae0140f02021-02-02 16:55:09 -08001821 // Initialize classical L2 PM Interval Counters
1822 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1823 // There is no way we should be landing here, but if we do then
1824 // there is nothing much we can do about this other than log error
1825 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1826 }
1827
mpagenkofc4f56e2020-11-04 17:17:49 +00001828 dh.ReadyForSpecificOmciConfig = true
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001829
1830 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1831 if pDevEntry == nil {
1832 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1833 return
1834 }
1835 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
1836 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1837 log.Fields{"device-id": dh.deviceID})
1838 go dh.reconcileDeviceTechProf(ctx)
1839 // reconcilement will be continued after ani config is done
1840 } else {
1841 // *** should generate UniUnlockStateDone event *****
1842 if dh.pUnlockStateFsm == nil {
1843 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1844 } else { //UnlockStateFSM already init
1845 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1846 dh.runUniLockFsm(ctx, false)
1847 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301848 }
1849}
1850
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1852 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301853
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001854 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001855 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301856 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1858 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001859 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001861 return
1862 }
1863 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 if err := dh.storePersistentData(ctx); err != nil {
1865 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001866 log.Fields{"device-id": dh.deviceID, "err": err})
1867 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301868 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 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 +05301870 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001872 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301873 }
1874}
1875
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1877 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001878 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001880 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1881 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001883 }
1884
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001886 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001888
1889 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001891
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001893 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001895 return
1896 }
1897 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 if err := dh.storePersistentData(ctx); err != nil {
1899 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001900 log.Fields{"device-id": dh.deviceID, "err": err})
1901 }
mpagenko900ee4b2020-10-12 11:56:34 +00001902}
1903
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1905 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001906 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001908 voltha.OperStatus_ACTIVE); err != nil {
1909 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001911 }
1912
dbainbri4d3a0dc2020-12-02 00:33:42 +00001913 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001914 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001915 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001917
1918 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001920
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001922 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001924 return
1925 }
1926 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 if err := dh.storePersistentData(ctx); err != nil {
1928 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001929 log.Fields{"device-id": dh.deviceID, "err": err})
1930 }
mpagenko900ee4b2020-10-12 11:56:34 +00001931}
1932
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001934 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001936 // attention: the device reason update is done based on ONU-UNI-Port related activity
1937 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001938 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001939 // 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 +00001940 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301941 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001942 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001944 }
1945 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001947 // attention: the device reason update is done based on ONU-UNI-Port related activity
1948 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001949 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001950 // 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 +00001951 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001952 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001953 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301954}
1955
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1957 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001958 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301959 // attention: the device reason update is done based on ONU-UNI-Port related activity
1960 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301961
mpagenkof1fc3862021-02-16 10:09:52 +00001962 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001963 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001964 // which may be the case from some previous actvity on another UNI Port of the ONU
1965 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001966 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1967 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001969 }
1970 }
1971 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001972 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001973 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001975 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301976 }
mpagenkof1fc3862021-02-16 10:09:52 +00001977
1978 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1979 //events that request KvStore write
1980 if err := dh.storePersistentData(ctx); err != nil {
1981 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1982 log.Fields{"device-id": dh.deviceID, "err": err})
1983 }
1984 } else {
1985 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
1986 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001987 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301988}
1989
Himani Chawla6d2ae152020-09-02 13:11:20 +05301990//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301992 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001993 case MibDatabaseSync:
1994 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001996 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001997 case UniLockStateDone:
1998 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002000 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002001 case MibDownloadDone:
2002 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002004 }
2005 case UniUnlockStateDone:
2006 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002008 }
mpagenko900ee4b2020-10-12 11:56:34 +00002009 case UniEnableStateDone:
2010 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002012 }
2013 case UniDisableStateDone:
2014 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002016 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002017 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002018 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002020 }
mpagenkof1fc3862021-02-16 10:09:52 +00002021 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002022 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002024 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002025 default:
2026 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002028 }
2029 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002030}
2031
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002033 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002034 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302035 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002036 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002037 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002038 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302039 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002040 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002041 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002043 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002044 //store UniPort with the System-PortNumber key
2045 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002046 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002047 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2049 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002050 } //error logging already within UniPort method
2051 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002053 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002054 }
2055 }
2056}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002057
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002058func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2059 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2060 if pDevEntry == nil {
2061 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2062 return
2063 }
2064 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2065 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2066 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2067 for _, mgmtEntityID := range pptpInstKeys {
2068 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2069 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2070 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2071 i++
2072 }
2073 } else {
2074 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2075 }
2076 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2077 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2078 for _, mgmtEntityID := range veipInstKeys {
2079 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2080 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2081 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2082 i++
2083 }
2084 } else {
2085 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2086 }
2087 if i == 0 {
2088 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2089 }
2090}
2091
mpagenko3af1f032020-06-10 08:53:41 +00002092// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002094 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302095 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002096 // with following remark:
2097 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2098 // # load on the core
2099
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002100 // 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 +00002101
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002102 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002103 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302104 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302106 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002107 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002108 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109 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 +00002110 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002112 }
mpagenko3af1f032020-06-10 08:53:41 +00002113 }
2114 }
2115}
2116
2117// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002118func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002119 // compare enableUniPortStateUpdate() above
2120 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2121 for uniNo, uniPort := range dh.uniEntityMap {
2122 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302123 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302125 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002126 if !dh.isReconciling() {
2127 //maybe also use getter functions on uniPort - perhaps later ...
2128 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2129 } else {
2130 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2131 }
2132
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002133 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002134 }
2135}
2136
2137// ONU_Active/Inactive announcement on system KAFKA bus
2138// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002139func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002140 var de voltha.DeviceEvent
2141 eventContext := make(map[string]string)
2142 //Populating event context
2143 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002145 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002146 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302147 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002148 }
2149 oltSerialNumber := parentDevice.SerialNumber
2150
2151 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2152 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2153 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302154 eventContext["olt-serial-number"] = oltSerialNumber
2155 eventContext["device-id"] = aDeviceID
2156 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002158 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002159
2160 /* Populating device event body */
2161 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302162 de.ResourceId = aDeviceID
2163 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002164 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2165 de.Description = fmt.Sprintf("%s Event - %s - %s",
2166 cEventObjectType, cOnuActivatedEvent, "Raised")
2167 } else {
2168 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2169 de.Description = fmt.Sprintf("%s Event - %s - %s",
2170 cEventObjectType, cOnuActivatedEvent, "Cleared")
2171 }
2172 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2174 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302175 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002176 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302178 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002179}
2180
Himani Chawla4d908332020-08-31 12:30:20 +05302181// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002183 chLSFsm := make(chan Message, 2048)
2184 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302185 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002187 sFsmName = "LockStateFSM"
2188 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002190 sFsmName = "UnLockStateFSM"
2191 }
mpagenko3af1f032020-06-10 08:53:41 +00002192
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002194 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002196 return
2197 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002199 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002200 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302201 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002202 dh.pLockStateFsm = pLSFsm
2203 } else {
2204 dh.pUnlockStateFsm = pLSFsm
2205 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002207 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002209 }
2210}
2211
2212// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002214 /* Uni Port lock/unlock procedure -
2215 ***** should run via 'adminDone' state and generate the argument requested event *****
2216 */
2217 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302218 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002219 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2220 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2221 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002222 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302223 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002224 }
2225 } else {
2226 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2227 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2228 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002229 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302230 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002231 }
2232 }
2233 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002234 if pLSStatemachine.Is(uniStDisabled) {
2235 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002237 // maybe try a FSM reset and then again ... - TODO!!!
2238 } else {
2239 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002241 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002242 }
2243 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002245 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002246 // maybe try a FSM reset and then again ... - TODO!!!
2247 }
2248 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002250 // maybe try a FSM reset and then again ... - TODO!!!
2251 }
2252}
2253
mpagenko80622a52021-02-09 16:53:23 +00002254// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002255func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002256 //in here lockUpgradeFsm is already locked
2257 chUpgradeFsm := make(chan Message, 2048)
2258 var sFsmName = "OnuSwUpgradeFSM"
2259 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002260 if apDevEntry.PDevOmciCC == nil {
2261 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2262 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002263 }
mpagenko15ff4a52021-03-02 10:09:20 +00002264 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002265 sFsmName, chUpgradeFsm)
2266 if dh.pOnuUpradeFsm != nil {
2267 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2268 if pUpgradeStatemachine != nil {
2269 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2270 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2271 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2272 // maybe try a FSM reset and then again ... - TODO!!!
2273 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2274 }
2275 /***** LockStateFSM started */
2276 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2277 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2278 } else {
2279 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2280 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2281 // maybe try a FSM reset and then again ... - TODO!!!
2282 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2283 }
2284 } else {
2285 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2286 // maybe try a FSM reset and then again ... - TODO!!!
2287 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2288 }
2289 } else {
2290 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2291 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2292 }
2293 return nil
2294}
2295
2296// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2297func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2298 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2299 "device-id": dh.deviceID})
2300 dh.lockUpgradeFsm.Lock()
2301 defer dh.lockUpgradeFsm.Unlock()
2302 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2303}
2304
mpagenko15ff4a52021-03-02 10:09:20 +00002305// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2306func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2307 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2308 if pDevEntry == nil {
2309 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2310 return
2311 }
2312
2313 dh.lockUpgradeFsm.RLock()
2314 defer dh.lockUpgradeFsm.RUnlock()
2315 if dh.pOnuUpradeFsm != nil {
2316 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2317 if pUpgradeStatemachine != nil {
2318 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2319 // (some manual forced commit could do without)
2320 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002321 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002322 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2323 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2324 return
2325 }
2326 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2327 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2328 } else {
2329 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2330 log.Fields{"device-id": dh.deviceID})
2331 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2332 return
2333 }
2334 }
2335 }
2336 } else {
2337 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2338 }
2339}
2340
Himani Chawla6d2ae152020-09-02 13:11:20 +05302341//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002342func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002343
2344 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002345 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002346 kvbackend := &db.Backend{
2347 Client: dh.pOpenOnuAc.kvClient,
2348 StoreType: dh.pOpenOnuAc.KVStoreType,
2349 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002350 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002351 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2352 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002353
mpagenkoaf801632020-07-03 10:00:42 +00002354 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002355}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302357 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002358
mpagenkodff5dda2020-08-28 11:52:01 +00002359 for _, field := range flow.GetOfbFields(apFlowItem) {
2360 switch field.Type {
2361 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2362 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002364 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2365 }
mpagenko01e726e2020-10-23 09:45:29 +00002366 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002367 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2368 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002370 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302371 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2372 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002373 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2374 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002375 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2376 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 return
mpagenkodff5dda2020-08-28 11:52:01 +00002378 }
2379 }
mpagenko01e726e2020-10-23 09:45:29 +00002380 */
mpagenkodff5dda2020-08-28 11:52:01 +00002381 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2382 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302383 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002384 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302385 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002386 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302387 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002388 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302390 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002391 }
2392 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2393 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302394 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002396 "PCP": loAddPcp})
2397 }
2398 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2399 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002401 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2402 }
2403 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2404 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002406 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2407 }
2408 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2409 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002411 "IPv4-DST": field.GetIpv4Dst()})
2412 }
2413 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2414 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002416 "IPv4-SRC": field.GetIpv4Src()})
2417 }
2418 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2419 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002420 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002421 "Metadata": field.GetTableMetadata()})
2422 }
2423 /*
2424 default:
2425 {
2426 //all other entires ignored
2427 }
2428 */
2429 }
2430 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302431}
mpagenkodff5dda2020-08-28 11:52:01 +00002432
dbainbri4d3a0dc2020-12-02 00:33:42 +00002433func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002434 for _, action := range flow.GetActions(apFlowItem) {
2435 switch action.Type {
2436 /* not used:
2437 case of.OfpActionType_OFPAT_OUTPUT:
2438 {
mpagenko01e726e2020-10-23 09:45:29 +00002439 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002440 "Output": action.GetOutput()})
2441 }
2442 */
2443 case of.OfpActionType_OFPAT_PUSH_VLAN:
2444 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002446 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2447 }
2448 case of.OfpActionType_OFPAT_SET_FIELD:
2449 {
2450 pActionSetField := action.GetSetField()
2451 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002453 "OxcmClass": pActionSetField.Field.OxmClass})
2454 }
2455 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302456 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302458 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002459 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302460 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302462 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002463 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002465 "Type": pActionSetField.Field.GetOfbField().Type})
2466 }
2467 }
2468 /*
2469 default:
2470 {
2471 //all other entires ignored
2472 }
2473 */
2474 }
2475 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302476}
2477
2478//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302480 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2481 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2482 var loAddPcp, loSetPcp uint8
2483 var loIPProto uint32
2484 /* the TechProfileId is part of the flow Metadata - compare also comment within
2485 * OLT-Adapter:openolt_flowmgr.go
2486 * Metadata 8 bytes:
2487 * Most Significant 2 Bytes = Inner VLAN
2488 * Next 2 Bytes = Tech Profile ID(TPID)
2489 * Least Significant 4 Bytes = Port ID
2490 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2491 * subscriber related flows.
2492 */
2493
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302495 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302497 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002498 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302499 }
mpagenko551a4d42020-12-08 18:09:20 +00002500 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002501 loCookie := apFlowItem.GetCookie()
2502 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002503 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002504 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302505
dbainbri4d3a0dc2020-12-02 00:33:42 +00002506 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002507 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302508 if loIPProto == 2 {
2509 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2510 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002511 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2512 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302513 return nil
2514 }
mpagenko01e726e2020-10-23 09:45:29 +00002515 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002516 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002517
2518 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002520 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2521 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2522 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2523 //TODO!!: Use DeviceId within the error response to rwCore
2524 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002525 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002526 }
2527 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002529 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2530 } else {
2531 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2532 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2533 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302534 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002535 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002537 }
mpagenko9a304ea2020-12-16 15:54:01 +00002538
2539 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002540 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002541 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302542 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002543 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002544 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002545 dh.lockVlanConfig.RUnlock()
2546 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002547 }
mpagenkof1fc3862021-02-16 10:09:52 +00002548 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002550 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002551}
2552
2553//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002554func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002555 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2556 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2557 //no extra check is done on the rule parameters
2558 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2559 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2560 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2561 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002562 // - 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 +00002563 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002564 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002565
2566 /* TT related temporary workaround - should not be needed anymore
2567 for _, field := range flow.GetOfbFields(apFlowItem) {
2568 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2569 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002570 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002571 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2572 if loIPProto == 2 {
2573 // 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 +00002574 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002575 log.Fields{"device-id": dh.deviceID})
2576 return nil
2577 }
2578 }
2579 } //for all OfbFields
2580 */
2581
mpagenko9a304ea2020-12-16 15:54:01 +00002582 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002583 dh.lockVlanConfig.RLock()
2584 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002585 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002586 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002587 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002588 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002589 log.Fields{"device-id": dh.deviceID})
2590 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002591 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002592 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002593
mpagenko01e726e2020-10-23 09:45:29 +00002594 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002595}
2596
Himani Chawla26e555c2020-08-31 12:30:20 +05302597// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002598// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002599func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002600 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002601 chVlanFilterFsm := make(chan Message, 2048)
2602
dbainbri4d3a0dc2020-12-02 00:33:42 +00002603 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002604 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302606 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002607 }
2608
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002610 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2611 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002612 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002613 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002614 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2615 // (from parallel processing)
2616 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302617 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002618 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2619 if pVlanFilterStatemachine != nil {
2620 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2621 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302623 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002624 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302625 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002626 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302627 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2628 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002629 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002631 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302632 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002633 }
2634 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002635 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002636 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302637 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002638 }
2639 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002641 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302642 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002643 }
2644 return nil
2645}
2646
mpagenkofc4f56e2020-11-04 17:17:49 +00002647//VerifyVlanConfigRequest checks on existence of a given uniPort
2648// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002649func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002650 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2651 var pCurrentUniPort *onuUniPort
2652 for _, uniPort := range dh.uniEntityMap {
2653 // only if this port is validated for operState transfer
2654 if uniPort.uniID == uint8(aUniID) {
2655 pCurrentUniPort = uniPort
2656 break //found - end search loop
2657 }
2658 }
2659 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002660 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002661 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2662 return
2663 }
mpagenko551a4d42020-12-08 18:09:20 +00002664 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002665}
2666
mpagenkodff5dda2020-08-28 11:52:01 +00002667//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002668func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002669 //TODO!! verify and start pending flow configuration
2670 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2671 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002672
2673 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302674 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002675 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002676 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2677 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2678 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002679 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2680 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2681 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2682 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2683 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2684 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2685 } else {
2686 /***** UniVlanConfigFsm continued */
2687 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2688 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2689 "UniPort": apUniPort.portNo})
2690 }
2691 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2692 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2693 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2694 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2695 } else {
2696 /***** UniVlanConfigFsm continued */
2697 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2698 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2699 "UniPort": apUniPort.portNo})
2700 }
mpagenkodff5dda2020-08-28 11:52:01 +00002701 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002702 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2703 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002704 "UniPort": apUniPort.portNo})
2705 }
2706 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002707 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2708 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2709 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002710 }
2711 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002712 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002713 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002714 }
mpagenkof1fc3862021-02-16 10:09:52 +00002715 } else {
2716 dh.lockVlanConfig.RUnlock()
2717 }
mpagenkodff5dda2020-08-28 11:52:01 +00002718}
2719
2720//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2721// 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 +00002722func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2723 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002724 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2725 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002726 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302727 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002728 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002729}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002730
Girish Gowdra26a40922021-01-29 17:14:34 -08002731//ProcessPendingTpDelete processes any pending TP delete (if available)
2732func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2733 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2734 if apUniPort == nil {
2735 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2736 return
2737 }
2738 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2739 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2740 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2741 if pAniConfigStatemachine != nil {
2742 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2743 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2744 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2745 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2746 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2747 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2748 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2749 return
2750 }
2751 } else {
2752 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2753 return
2754 }
2755 }
2756 return
2757 }
2758}
2759
mpagenkof1fc3862021-02-16 10:09:52 +00002760//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2761func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2762 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2763 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2764 // obviously then parallel processing on the cancel must be avoided
2765 // deadline context to ensure completion of background routines waited for
2766 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2767 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2768 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2769
2770 aPDevEntry.resetKvProcessingErrorIndication()
2771 var wg sync.WaitGroup
2772 wg.Add(1) // for the 1 go routine to finish
2773
2774 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2775 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2776
2777 return aPDevEntry.getKvProcessingErrorIndication()
2778}
2779
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002780//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2781//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002782func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2783 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002784
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002785 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002786 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002787 return nil
2788 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002789 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002790
dbainbri4d3a0dc2020-12-02 00:33:42 +00002791 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002792 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002793 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002794 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2795 }
2796 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2797
mpagenkof1fc3862021-02-16 10:09:52 +00002798 if aWriteToKvStore {
2799 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2800 }
2801 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002802}
2803
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002805 defer cancel() //ensure termination of context (may be pro forma)
2806 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002808 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002809}
2810
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002812
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002813 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002814 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002815 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002816 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2817 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002818 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002819 return err
2820 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002821 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002822 return nil
2823 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002824 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002825 return nil
2826}
2827
dbainbri4d3a0dc2020-12-02 00:33:42 +00002828func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2829 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002830 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002831 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002832 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2833 }
mpagenkof1fc3862021-02-16 10:09:52 +00002834 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002835}
2836
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002837func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2838 var errStr string = ""
2839 for _, err := range errS {
2840 if err != nil {
2841 errStr = errStr + err.Error() + " "
2842 }
2843 }
2844 if errStr != "" {
2845 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2846 }
2847 return nil
2848}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002849
2850// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2851func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2852 dh.lockDevice.RLock()
2853 defer dh.lockDevice.RUnlock()
2854 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2855 return uniPort.entityID, nil
2856 }
2857 return 0, errors.New("error-fetching-uni-port")
2858}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002859
2860// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002861func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2862 var errorsList []error
2863 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 -08002864
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002865 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2866 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2867 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2868
2869 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2870 // successfully.
2871 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2872 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2873 if len(errorsList) > 0 {
2874 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2875 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002876 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002877 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2878 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002879}
2880
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002881func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2882 var err error
2883 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002884 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002885
2886 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2887 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2888 errorsList = append(errorsList, err)
2889 }
2890 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002891 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002892
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002893 return errorsList
2894}
2895
2896func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2897 var err error
2898 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002899 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002900 // Check if group metric related config is updated
2901 for _, v := range pmConfigs.Groups {
2902 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2903 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2904 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2905
2906 if ok && m.frequency != v.GroupFreq {
2907 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2908 errorsList = append(errorsList, err)
2909 }
2910 }
2911 if ok && m.enabled != v.Enabled {
2912 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2913 errorsList = append(errorsList, err)
2914 }
2915 }
2916 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002917 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002918 return errorsList
2919}
2920
2921func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2922 var err error
2923 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002924 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002925 // Check if standalone metric related config is updated
2926 for _, v := range pmConfigs.Metrics {
2927 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002928 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002929 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2930
2931 if ok && m.frequency != v.SampleFreq {
2932 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2933 errorsList = append(errorsList, err)
2934 }
2935 }
2936 if ok && m.enabled != v.Enabled {
2937 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2938 errorsList = append(errorsList, err)
2939 }
2940 }
2941 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002942 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002943 return errorsList
2944}
2945
2946// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002947func (dh *deviceHandler) startCollector(ctx context.Context) {
2948 logger.Debugf(ctx, "startingCollector")
2949
2950 // Start routine to process OMCI GET Responses
2951 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002952 // Initialize the next metric collection time.
2953 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2954 // reset like onu rebooted.
2955 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002956 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002957 for {
2958 select {
2959 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002960 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002961 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002962 // Stop the L2 PM FSM
2963 go func() {
2964 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2965 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2966 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2967 }
2968 } else {
2969 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2970 }
2971 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002972 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2973 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2974 }
2975 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2976 dh.pOnuMetricsMgr.stopTicks <- true
2977 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002978
Girish Gowdrae09a6202021-01-12 18:10:59 -08002979 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002980 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2981 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2982 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2983 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2984 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002985 // Update the next metric collection time.
2986 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002987 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002988 } else {
2989 if dh.pmConfigs.Grouped { // metrics are managed as a group
2990 // parse through the group and standalone metrics to see it is time to collect their metrics
2991 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002992
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002993 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2994 // 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 -08002995 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2996 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002997 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2998 }
2999 }
3000 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3001 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3002 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3003 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3004 }
3005 }
3006 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3007
3008 // parse through the group and update the next metric collection time
3009 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3010 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3011 // 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 -08003012 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3013 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003014 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3015 }
3016 }
3017 // parse through the standalone metrics and update the next metric collection time
3018 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3019 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3020 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3021 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3022 }
3023 }
3024 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3025 } /* else { // metrics are not managed as a group
3026 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3027 } */
3028 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003029 }
3030 }
3031}
kesavandfdf77632021-01-26 23:40:33 -05003032
3033func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3034
3035 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3036 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3037}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003038
mpagenkof1fc3862021-02-16 10:09:52 +00003039func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3040 if pFsm == nil {
3041 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003042 }
mpagenkof1fc3862021-02-16 10:09:52 +00003043 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003044}
3045
mpagenkof1fc3862021-02-16 10:09:52 +00003046func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3047 var pFsm *fsm.FSM
3048 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3049 switch omciFsm {
3050 case cUploadFsm:
3051 {
3052 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3053 }
3054 case cDownloadFsm:
3055 {
3056 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3057 }
3058 case cUniLockFsm:
3059 {
3060 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3061 }
3062 case cUniUnLockFsm:
3063 {
3064 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3065 }
3066 case cL2PmFsm:
3067 {
3068 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3069 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3070 } else {
3071 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003072 }
3073 }
mpagenko80622a52021-02-09 16:53:23 +00003074 case cOnuUpgradeFsm:
3075 {
3076 dh.lockUpgradeFsm.RLock()
3077 defer dh.lockUpgradeFsm.RUnlock()
3078 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3079 }
mpagenkof1fc3862021-02-16 10:09:52 +00003080 default:
3081 {
3082 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3083 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3084 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003085 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003086 }
mpagenkof1fc3862021-02-16 10:09:52 +00003087 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003088}
3089
mpagenkof1fc3862021-02-16 10:09:52 +00003090func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3091 for _, v := range dh.pOnuTP.pAniConfigFsm {
3092 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003093 return false
3094 }
3095 }
3096 return true
3097}
3098
mpagenkof1fc3862021-02-16 10:09:52 +00003099func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3100 dh.lockVlanConfig.RLock()
3101 defer dh.lockVlanConfig.RUnlock()
3102 for _, v := range dh.UniVlanConfigFsmMap {
3103 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3104 return false
3105 }
3106 }
3107 return true //FSM not active - so there is no activity on omci
3108}
3109
3110func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3111 dh.lockVlanConfig.RLock()
3112 defer dh.lockVlanConfig.RUnlock()
3113 for _, v := range dh.UniVlanConfigFsmMap {
3114 if v.pAdaptFsm.pFsm != nil {
3115 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3116 return true //there is at least one VLAN FSM with some active configuration
3117 }
3118 }
3119 }
3120 return false //there is no VLAN FSM with some active configuration
3121}
3122
3123func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3124 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3125 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3126 return false
3127 }
3128 }
3129 // a further check is done to identify, if at least some data traffic related configuration exists
3130 // 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])
3131 return dh.checkUserServiceExists(ctx)
3132}
3133
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003134func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3135 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3136 if err := dh.resetFsms(ctx, false); err != nil {
3137 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3138 // TODO: fatal error reset ONU, delete deviceHandler!
3139 return
3140 }
3141 if !dh.getCollectorIsRunning() {
3142 // Start PM collector routine
3143 go dh.startCollector(ctx)
3144 }
Himani Chawla1472c682021-03-17 17:11:14 +05303145 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303146 go dh.startAlarmManager(ctx)
3147 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003148 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003149 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003150}
3151
3152func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3153 dh.mutexCollectorFlag.Lock()
3154 dh.collectorIsRunning = flagValue
3155 dh.mutexCollectorFlag.Unlock()
3156}
3157
3158func (dh *deviceHandler) getCollectorIsRunning() bool {
3159 dh.mutexCollectorFlag.RLock()
3160 flagValue := dh.collectorIsRunning
3161 dh.mutexCollectorFlag.RUnlock()
3162 return flagValue
3163}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303164
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303165func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3166 dh.mutextAlarmManagerFlag.Lock()
3167 dh.alarmManagerIsRunning = flagValue
3168 dh.mutextAlarmManagerFlag.Unlock()
3169}
3170
Himani Chawla1472c682021-03-17 17:11:14 +05303171func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303172 dh.mutextAlarmManagerFlag.RLock()
3173 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303174 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303175 dh.mutextAlarmManagerFlag.RUnlock()
3176 return flagValue
3177}
3178
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303179func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3180 logger.Debugf(ctx, "startingAlarmManager")
3181
3182 // Start routine to process OMCI GET Responses
3183 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303184 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303185 if stop := <-dh.stopAlarmManager; stop {
3186 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303187 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303188 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303189 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3190 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3191 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303192 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303193 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303194 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3195 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303196 }
3197}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003198
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003199func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
3200 logger.Debugw(ctx, "start reconciling", log.Fields{"withOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
3201
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003202 if !dh.isReconciling() {
3203 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003204 logger.Debugw(ctx, "wait for channel signal or timeout",
3205 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003206 select {
3207 case <-dh.chReconcilingFinished:
3208 logger.Debugw(ctx, "reconciling has been finished in time",
3209 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003210 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003211 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3212 log.Fields{"device-id": dh.deviceID})
3213 }
3214 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003215 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003216 dh.mutexReconcilingFlag.Unlock()
3217 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003218 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003219 dh.mutexReconcilingFlag.Lock()
3220 if skipOnuConfig {
3221 dh.reconciling = cSkipOnuConfigReconciling
3222 } else {
3223 dh.reconciling = cOnuConfigReconciling
3224 }
3225 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003226}
3227
3228func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3229 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3230 if dh.isReconciling() {
3231 dh.chReconcilingFinished <- true
3232 } else {
3233 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3234 }
3235}
3236
3237func (dh *deviceHandler) isReconciling() bool {
3238 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003239 defer dh.mutexReconcilingFlag.RUnlock()
3240 return dh.reconciling != cNoReconciling
3241}
3242
3243func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3244 dh.mutexReconcilingFlag.RLock()
3245 defer dh.mutexReconcilingFlag.RUnlock()
3246 return dh.reconciling == cSkipOnuConfigReconciling
3247}
3248
3249func (dh *deviceHandler) setDeviceReason(value uint8) {
3250 dh.mutexDeviceReason.Lock()
3251 dh.deviceReason = value
3252 dh.mutexDeviceReason.Unlock()
3253}
3254
3255func (dh *deviceHandler) getDeviceReason() uint8 {
3256 dh.mutexDeviceReason.RLock()
3257 value := dh.deviceReason
3258 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003259 return value
3260}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003261
3262func (dh *deviceHandler) getDeviceReasonString() string {
3263 return deviceReasonMap[dh.getDeviceReason()]
3264}