blob: 7d2d2262a1fff4db9a2dea7c57b37f159633fab6 [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"
22 "encoding/hex"
23 "errors"
24 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
34 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053035 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000036 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v4/pkg/log"
38 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050039 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000040 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
41 "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v4/go/openolt"
45 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000046)
47
48/*
49// Constants for number of retries and for timeout
50const (
51 MaxRetry = 10
52 MaxTimeOutInMs = 500
53)
54*/
55
mpagenko1cc3cb42020-07-27 15:24:38 +000056const (
57 // events of Device FSM
58 devEvDeviceInit = "devEvDeviceInit"
59 devEvGrpcConnected = "devEvGrpcConnected"
60 devEvGrpcDisconnected = "devEvGrpcDisconnected"
61 devEvDeviceUpInd = "devEvDeviceUpInd"
62 devEvDeviceDownInd = "devEvDeviceDownInd"
63)
64const (
65 // states of Device FSM
66 devStNull = "devStNull"
67 devStDown = "devStDown"
68 devStInit = "devStInit"
69 devStConnected = "devStConnected"
70 devStUp = "devStUp"
71)
72
Holger Hildebrandt24d51952020-05-04 14:03:42 +000073//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
74const (
Himani Chawla4d908332020-08-31 12:30:20 +053075 pon = voltha.EventSubCategory_PON
76 //olt = voltha.EventSubCategory_OLT
77 //ont = voltha.EventSubCategory_ONT
78 //onu = voltha.EventSubCategory_ONU
79 //nni = voltha.EventSubCategory_NNI
80 //service = voltha.EventCategory_SERVICE
81 //security = voltha.EventCategory_SECURITY
82 equipment = voltha.EventCategory_EQUIPMENT
83 //processing = voltha.EventCategory_PROCESSING
84 //environment = voltha.EventCategory_ENVIRONMENT
85 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000086)
87
88const (
89 cEventObjectType = "ONU"
90)
91const (
92 cOnuActivatedEvent = "ONU_ACTIVATED"
93)
94
Holger Hildebrandt10d98192021-01-27 15:29:31 +000095type usedOmciConfigFsms int
96
97const (
98 cUploadFsm usedOmciConfigFsms = iota
99 cDownloadFsm
100 cUniLockFsm
101 cUniUnLockFsm
102 cAniConfigFsm
103 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800104 cL2PmFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
107type idleCheckStruct struct {
108 idleCheckFunc func(*deviceHandler, context.Context, string) bool
109 idleState string
110}
111
112var fsmIdleStateFuncMap = map[usedOmciConfigFsms]idleCheckStruct{
113 cUploadFsm: {(*deviceHandler).mibUploadFsmInIdleState, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).mibDownloadFsmInIdleState, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).devUniLockFsmInIdleState, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).devUniUnlockFsmInIdleState, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).devAniConfigFsmInIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).devUniVlanConfigFsmInIdleState, cVlanFsmIdleState},
Girish Gowdrae0140f02021-02-02 16:55:09 -0800119 cL2PmFsm: {(*deviceHandler).l2PmFsmInIdleState, cL2PmFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000122const (
123 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000124 drUnset = 0
125 drActivatingOnu = 1
126 drStartingOpenomci = 2
127 drDiscoveryMibsyncComplete = 3
128 drInitialMibDownloaded = 4
129 drTechProfileConfigDownloadSuccess = 5
130 drOmciFlowsPushed = 6
131 drOmciAdminLock = 7
132 drOnuReenabled = 8
133 drStoppingOpenomci = 9
134 drRebooting = 10
135 drOmciFlowsDeleted = 11
136 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000137)
138
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000139var deviceReasonMap = map[uint8]string{
140 drUnset: "unset",
141 drActivatingOnu: "activating-onu",
142 drStartingOpenomci: "starting-openomci",
143 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
144 drInitialMibDownloaded: "initial-mib-downloaded",
145 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
146 drOmciFlowsPushed: "omci-flows-pushed",
147 drOmciAdminLock: "omci-admin-lock",
148 drOnuReenabled: "onu-reenabled",
149 drStoppingOpenomci: "stopping-openomci",
150 drRebooting: "rebooting",
151 drOmciFlowsDeleted: "omci-flows-deleted",
152 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
153}
154
Himani Chawla6d2ae152020-09-02 13:11:20 +0530155//deviceHandler will interact with the ONU ? device.
156type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000157 deviceID string
158 DeviceType string
159 adminState string
160 device *voltha.Device
161 logicalDeviceID string
162 ProxyAddressID string
163 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530164 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000165 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000166
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000167 coreProxy adapterif.CoreProxy
168 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530169 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000170
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800171 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800172
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173 pOpenOnuAc *OpenONUAC
174 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530175 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000176 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000177 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530178 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800179 pOnuMetricsMgr *onuMetricsManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180 exitChannel chan int
181 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000182 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000183 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530184 pLockStateFsm *lockStateFsm
185 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 //flowMgr *OpenOltFlowMgr
188 //eventMgr *OpenOltEventMgr
189 //resourceMgr *rsrcMgr.OpenOltResourceMgr
190
191 //discOnus sync.Map
192 //onus sync.Map
193 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000194 collectorIsRunning bool
195 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000196 stopCollector chan bool
197 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000198 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000199 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000200 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
201 reconciling bool
202 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000203}
204
Himani Chawla6d2ae152020-09-02 13:11:20 +0530205//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530206func 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 +0530207 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000208 dh.coreProxy = cp
209 dh.AdapterProxy = ap
210 dh.EventProxy = ep
211 cloned := (proto.Clone(device)).(*voltha.Device)
212 dh.deviceID = cloned.Id
213 dh.DeviceType = cloned.Type
214 dh.adminState = "up"
215 dh.device = cloned
216 dh.pOpenOnuAc = adapter
217 dh.exitChannel = make(chan int, 1)
218 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000219 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000220 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000221 dh.stopCollector = make(chan bool, 2)
222 dh.stopHeartbeatCheck = make(chan bool, 2)
223 //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 +0000224 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530225 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000226 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000227 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000228 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000229 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800231 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
232 dh.pmConfigs = cloned.PmConfigs
233 } /* else {
234 // will be populated when onu_metrics_mananger is initialized.
235 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800236
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237 // Device related state machine
238 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000239 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000241 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
242 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
243 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
244 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
245 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 },
247 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000248 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
249 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
250 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
251 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
252 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
253 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
254 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
255 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 },
257 )
mpagenkoaf801632020-07-03 10:00:42 +0000258
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 return &dh
260}
261
Himani Chawla6d2ae152020-09-02 13:11:20 +0530262// start save the device to the data model
263func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000264 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000265 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000266 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267}
268
Himani Chawla4d908332020-08-31 12:30:20 +0530269/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530271func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272 logger.Debug("stopping-device-handler")
273 dh.exitChannel <- 1
274}
Himani Chawla4d908332020-08-31 12:30:20 +0530275*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276
277// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530278// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279
Girish Gowdrae0140f02021-02-02 16:55:09 -0800280//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530281func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000282 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000285 if dh.pDeviceStateFsm.Is(devStNull) {
286 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800290 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
291 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800292 // Now, set the initial PM configuration for that device
293 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
294 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
295 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800296 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299 }
300
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000301}
302
mpagenko057889c2021-01-21 16:51:58 +0000303func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530304 msgBody := msg.GetBody()
305 omciMsg := &ic.InterAdapterOmciMessage{}
306 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000307 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530308 "device-id": dh.deviceID, "error": err})
309 return err
310 }
311
312 //assuming omci message content is hex coded!
313 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000314 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530315 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
316 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000317 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530318 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000319 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000321 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 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 +0530323 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000324 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000325 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530326}
327
Himani Chawla6d2ae152020-09-02 13:11:20 +0530328func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530330 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000331
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000333
dbainbri4d3a0dc2020-12-02 00:33:42 +0000334 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000335 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000337 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
338 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530339 if dh.pOnuTP == nil {
340 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000341 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000343 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530344 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000345 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000347 "device-state": deviceReasonMap[dh.deviceReason]})
348 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000350 //previous state test here was just this one, now extended for more states to reject the SetRequest:
351 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
352 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530353
354 msgBody := msg.GetBody()
355 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
356 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 "device-id": dh.deviceID, "error": err})
359 return err
360 }
361
362 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000363 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
364 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 defer dh.pOnuTP.unlockTpProcMutex()
367 pDevEntry.lockOnuKVStoreMutex()
368 defer pDevEntry.unlockOnuKVStoreMutex()
369
370 if techProfMsg.UniId > 255 {
371 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
372 techProfMsg.UniId, dh.deviceID))
373 }
374 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800375 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
376 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800378 return err
379 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 // if there has been some change for some uni TechProfilePath
383 //in order to allow concurrent calls to other dh instances we do not wait for execution here
384 //but doing so we can not indicate problems to the caller (who does what with that then?)
385 //by now we just assume straightforward successful execution
386 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
387 // possible problems to the caller later autonomously
388
389 // deadline context to ensure completion of background routines waited for
390 //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 +0530391 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 dctx, cancel := context.WithDeadline(context.Background(), deadline)
393
Girish Gowdra041dcb32020-11-16 16:54:30 -0800394 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395 pDevEntry.resetKvProcessingErrorIndication()
396
Himani Chawla26e555c2020-08-31 12:30:20 +0530397 var wg sync.WaitGroup
398 wg.Add(2) // for the 2 go routines to finish
399 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000400 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
401 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
402 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403
Girish Gowdra041dcb32020-11-16 16:54:30 -0800404 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 return nil
408}
409
Himani Chawla6d2ae152020-09-02 13:11:20 +0530410func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000411 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 msg *ic.InterAdapterMessage) error {
413
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000415
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
420 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530421 if dh.pOnuTP == nil {
422 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000423 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530426 }
427
428 msgBody := msg.GetBody()
429 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
430 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530432 "device-id": dh.deviceID, "error": err})
433 return err
434 }
435
436 //compare TECH_PROFILE_DOWNLOAD_REQUEST
437 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000438 defer dh.pOnuTP.unlockTpProcMutex()
439 pDevEntry.lockOnuKVStoreMutex()
440 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530441
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442 if delGemPortMsg.UniId > 255 {
443 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
444 delGemPortMsg.UniId, dh.deviceID))
445 }
446 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800447 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
448 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449 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 -0800450 return err
451 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530452
mpagenkofc4f56e2020-11-04 17:17:49 +0000453 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000454
mpagenkofc4f56e2020-11-04 17:17:49 +0000455 // deadline context to ensure completion of background routines waited for
456 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
457 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000458
Girish Gowdra041dcb32020-11-16 16:54:30 -0800459 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000460
mpagenkofc4f56e2020-11-04 17:17:49 +0000461 var wg sync.WaitGroup
462 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000464 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000465 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000466
Girish Gowdra041dcb32020-11-16 16:54:30 -0800467 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530468}
469
Himani Chawla6d2ae152020-09-02 13:11:20 +0530470func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000471 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000473
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000475
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
480 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 if dh.pOnuTP == nil {
482 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 }
487
488 msgBody := msg.GetBody()
489 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
490 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 "device-id": dh.deviceID, "error": err})
493 return err
494 }
495
496 //compare TECH_PROFILE_DOWNLOAD_REQUEST
497 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498 defer dh.pOnuTP.unlockTpProcMutex()
499 pDevEntry.lockOnuKVStoreMutex()
500 defer pDevEntry.unlockOnuKVStoreMutex()
501
502 if delTcontMsg.UniId > 255 {
503 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
504 delTcontMsg.UniId, dh.deviceID))
505 }
506 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800507 tpPath := delTcontMsg.TpPath
508 tpID, err := GetTpIDFromTpPath(tpPath)
509 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800511 return err
512 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530516 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530517 dctx, cancel := context.WithDeadline(context.Background(), deadline)
518
Girish Gowdra041dcb32020-11-16 16:54:30 -0800519 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 pDevEntry.resetKvProcessingErrorIndication()
521
Himani Chawla26e555c2020-08-31 12:30:20 +0530522 var wg sync.WaitGroup
523 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530525 cResourceTcont, delTcontMsg.AllocId, &wg)
526 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
528 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000529
Girish Gowdra041dcb32020-11-16 16:54:30 -0800530 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 return nil
533}
534
Himani Chawla6d2ae152020-09-02 13:11:20 +0530535//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000536// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
537// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000539 msgID := msg.Header.Id
540 msgType := msg.Header.Type
541 fromTopic := msg.Header.FromTopic
542 toTopic := msg.Header.ToTopic
543 toDeviceID := msg.Header.ToDeviceId
544 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000546 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
547
548 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000549 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000550 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
551 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000552 {
mpagenko057889c2021-01-21 16:51:58 +0000553 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000554 }
mpagenkoaf801632020-07-03 10:00:42 +0000555 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
556 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000557 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000558 }
559 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
560 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000561 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000562
mpagenkoaf801632020-07-03 10:00:42 +0000563 }
564 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
565 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000566 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000567 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000568 default:
569 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571 "msgType": msg.Header.Type, "device-id": dh.deviceID})
572 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000573 }
574 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000575}
576
mpagenkodff5dda2020-08-28 11:52:01 +0000577//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000578func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
579 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000580 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000582
mpagenko01e726e2020-10-23 09:45:29 +0000583 var retError error = nil
584 //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 +0000585 if apOfFlowChanges.ToRemove != nil {
586 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000587 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000589 "device-id": dh.deviceID})
590 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000591 continue
592 }
593 flowInPort := flow.GetInPort(flowItem)
594 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000595 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 +0000596 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
597 continue
598 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000599 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000600 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000601 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000602 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000603 continue
604 } else {
605 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530606 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000607 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
608 loUniPort = uniPort
609 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000610 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000611 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
612 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
613 flowInPort, dh.deviceID)
614 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000615 }
616 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000618 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000619 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000621 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000622 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000624 log.Fields{"device-id": dh.deviceID, "error": err})
625 retError = err
626 continue
627 //return err
628 } else { // if last setting succeeds, overwrite possibly previously set error
629 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000630 }
631 }
632 }
633 }
mpagenko01e726e2020-10-23 09:45:29 +0000634 if apOfFlowChanges.ToAdd != nil {
635 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
636 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000638 "device-id": dh.deviceID})
639 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
640 continue
641 }
642 flowInPort := flow.GetInPort(flowItem)
643 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 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 +0000645 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
646 continue
647 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
648 } else if flowInPort == dh.ponPortNumber {
649 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000651 "device-id": dh.deviceID, "inPort": flowInPort})
652 continue
653 } else {
654 // this is the relevant upstream flow
655 var loUniPort *onuUniPort
656 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
657 loUniPort = uniPort
658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000660 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
661 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
662 flowInPort, dh.deviceID)
663 continue
664 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
665 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000666 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
667 // if not, we just throw some error here to have an indication about that, if we really need to support that
668 // then we would need to create some means to activate the internal stored flows
669 // after the device gets active automatically (and still with its dependency to the TechProfile)
670 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
671 // also abort for the other still possible flows here
672 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000674 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 return fmt.Errorf("improper device state on device %s", dh.deviceID)
676 }
677
mpagenko01e726e2020-10-23 09:45:29 +0000678 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000680 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
681 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000683 //try next flow after processing error
684 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000686 log.Fields{"device-id": dh.deviceID, "error": err})
687 retError = err
688 continue
689 //return err
690 } else { // if last setting succeeds, overwrite possibly previously set error
691 retError = nil
692 }
693 }
694 }
695 }
696 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000697}
698
Himani Chawla6d2ae152020-09-02 13:11:20 +0530699//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000700//following are the expected device states after this activity:
701//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
702// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
704 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000705
mpagenko900ee4b2020-10-12 11:56:34 +0000706 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000707 //note that disableDevice sequences in some 'ONU active' state may yield also
708 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000709 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000710 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000711 //disable-device shall be just a UNi/ONU-G related admin state setting
712 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000713
mpagenkofc4f56e2020-11-04 17:17:49 +0000714 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000715 // disable UNI ports/ONU
716 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
717 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000719 } else { //LockStateFSM already init
720 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000722 }
723 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000725 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000727 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
728 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000730 }
mpagenko01e726e2020-10-23 09:45:29 +0000731 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000732
733 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000735 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300736 }
737}
738
Himani Chawla6d2ae152020-09-02 13:11:20 +0530739//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
741 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000742
mpagenkofc4f56e2020-11-04 17:17:49 +0000743 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
744 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
745 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
746 // for real ONU's that should have nearly no influence
747 // Note that for real ONU's there is anyway a problematic situation with following sequence:
748 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
749 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
750 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
751 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
752
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000753 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000754 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000755 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000757 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000758 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000760 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300761}
762
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
764 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000765
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000767 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000769 return
770 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000772 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000774 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000776 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000777 dh.reconciling = false
778 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000779 }
Himani Chawla4d908332020-08-31 12:30:20 +0530780 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000781 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
782 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
783 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
784 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000786}
787
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
789 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000790
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 return
795 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000796 dh.pOnuTP.lockTpProcMutex()
797 defer dh.pOnuTP.unlockTpProcMutex()
798
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000799 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000801 log.Fields{"device-id": dh.deviceID})
802 dh.reconciling = false
803 return
804 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000805 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000806 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
807 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000809 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
810 dh.reconciling = false
811 return
812 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800813 for tpID := range uniData.PersTpPathMap {
814 // deadline context to ensure completion of background routines waited for
815 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
816 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000818
Girish Gowdra041dcb32020-11-16 16:54:30 -0800819 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
820 var wg sync.WaitGroup
821 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
823 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800824 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800826 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000828 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000830 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
831 dh.reconciling = false
832 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000833 }
834}
835
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
837 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000840 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000842 return
843 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000844 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000846 log.Fields{"device-id": dh.deviceID})
847 dh.reconciling = false
848 return
849 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000850 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000851 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
852 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
855 dh.reconciling = false
856 return
857 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000858 var uniPort *onuUniPort
859 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863 return
864 }
865 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000867 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000868 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000869 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000870 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
871 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000873 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000876 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000877 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000879 }
880 }
881 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000884 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
885 dh.reconciling = false
886 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887 }
888}
889
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
891 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 +0000892
893 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000894 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000895}
896
dbainbri4d3a0dc2020-12-02 00:33:42 +0000897func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
898 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000901 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000902 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000903 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000904 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000905 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000906 pDevEntry.lockOnuKVStoreMutex()
907 defer pDevEntry.unlockOnuKVStoreMutex()
908
909 // deadline context to ensure completion of background routines waited for
910 //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 +0530911 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000912 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000913
914 pDevEntry.resetKvProcessingErrorIndication()
915
916 var wg sync.WaitGroup
917 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
919 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000920
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000923}
924
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
926 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300927 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000929 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300930 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000931 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530932 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000933 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530934 return err
935 }
mpagenko01e726e2020-10-23 09:45:29 +0000936
937 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000939
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000941 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300943 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000944 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300946 return err
947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300949 return err
950 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000951 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000952 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
953 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
954 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
955 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300956 return nil
957}
958
mpagenkoc8bba412021-01-15 15:38:44 +0000959//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
960func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
961 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
962 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000963 //return success to comfort the core processing during integration
964 return nil
965 // TODO!!: also verify error response behavior
966 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000967}
968
Himani Chawla6d2ae152020-09-02 13:11:20 +0530969// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000970// #####################################################################################
971
972// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530973// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000974
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
976 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 +0000977}
978
979// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981
dbainbri4d3a0dc2020-12-02 00:33:42 +0000982 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000983 var err error
984
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000985 // populate what we know. rest comes later after mib sync
986 dh.device.Root = false
987 dh.device.Vendor = "OpenONU"
988 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000989 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000990 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000991
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000992 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000993
994 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
996 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530997 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000998 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001000 log.Fields{"device-id": dh.deviceID})
1001 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001002
Himani Chawla4d908332020-08-31 12:30:20 +05301003 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001004 dh.ponPortNumber = dh.device.ParentPortNo
1005
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001006 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1007 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1008 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001010 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301011 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001012
1013 /*
1014 self._pon = PonPort.create(self, self._pon_port_number)
1015 self._pon.add_peer(self.parent_id, self._pon_port_number)
1016 self.logger.debug('adding-pon-port-to-agent',
1017 type=self._pon.get_port().type,
1018 admin_state=self._pon.get_port().admin_state,
1019 oper_status=self._pon.get_port().oper_status,
1020 )
1021 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001022 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001024 var ponPortNo uint32 = 1
1025 if dh.ponPortNumber != 0 {
1026 ponPortNo = dh.ponPortNumber
1027 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001028
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001029 pPonPort := &voltha.Port{
1030 PortNo: ponPortNo,
1031 Label: fmt.Sprintf("pon-%d", ponPortNo),
1032 Type: voltha.Port_PON_ONU,
1033 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301034 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001035 PortNo: ponPortNo}}, // Peer port is parent's port number
1036 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001037 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1038 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001039 e.Cancel(err)
1040 return
1041 }
1042 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001044 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001045 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001046}
1047
1048// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001052 var err error
1053 /*
1054 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1055 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1056 return nil
1057 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1059 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001060 e.Cancel(err)
1061 return
1062 }
1063
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001064 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001066 // reconcilement will be continued after mib download is done
1067 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001068
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069 /*
1070 ############################################################################
1071 # Setup Alarm handler
1072 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1073 device.serial_number)
1074 ############################################################################
1075 # Setup PM configuration for this device
1076 # Pass in ONU specific options
1077 kwargs = {
1078 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1079 'heartbeat': self.heartbeat,
1080 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1081 }
1082 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1083 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1084 self.logical_device_id, device.serial_number,
1085 grouped=True, freq_override=False, **kwargs)
1086 pm_config = self._pm_metrics.make_proto()
1087 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1088 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1089 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1090
1091 # Note, ONU ID and UNI intf set in add_uni_port method
1092 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1093 ani_ports=[self._pon])
1094
1095 # Code to Run OMCI Test Action
1096 kwargs_omci_test_action = {
1097 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1098 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1099 }
1100 serial_number = device.serial_number
1101 self._test_request = OmciTestRequest(self.core_proxy,
1102 self.omci_agent, self.device_id,
1103 AniG, serial_number,
1104 self.logical_device_id,
1105 exclusive=False,
1106 **kwargs_omci_test_action)
1107
1108 self.enabled = True
1109 else:
1110 self.logger.info('onu-already-activated')
1111 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001112
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114}
1115
1116// doStateConnected get the device info and update to voltha core
1117// for comparison of the original method (not that easy to uncomment): compare here:
1118// voltha-openolt-adapter/adaptercore/device_handler.go
1119// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301123 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001126}
1127
1128// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301132 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001134 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135
1136 /*
1137 // Synchronous call to update device state - this method is run in its own go routine
1138 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1139 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001140 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 +00001141 return err
1142 }
1143 return nil
1144 */
1145}
1146
1147// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001149
dbainbri4d3a0dc2020-12-02 00:33:42 +00001150 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001151 var err error
1152
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001153 device := dh.device
1154 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001157 e.Cancel(err)
1158 return
1159 }
1160
1161 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001163 /*
1164 // Update the all ports state on that device to disable
1165 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001166 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001167 return er
1168 }
1169
1170 //Update the device oper state and connection status
1171 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1172 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1173 dh.device = cloned
1174
1175 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001176 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001177 return er
1178 }
1179
1180 //get the child device for the parent device
1181 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1182 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001183 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001184 return err
1185 }
1186 for _, onuDevice := range onuDevices.Items {
1187
1188 // Update onu state as down in onu adapter
1189 onuInd := oop.OnuIndication{}
1190 onuInd.OperState = "down"
1191 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1192 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1193 if er != nil {
1194 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001195 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001196 //Do not return here and continue to process other ONUs
1197 }
1198 }
1199 // * Discovered ONUs entries need to be cleared , since after OLT
1200 // is up, it starts sending discovery indications again* /
1201 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001202 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203 return nil
1204 */
Himani Chawla4d908332020-08-31 12:30:20 +05301205 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001207 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001208}
1209
Himani Chawla6d2ae152020-09-02 13:11:20 +05301210// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001211// #################################################################################
1212
1213// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301214// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001215
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001216//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001218 dh.lockDevice.RLock()
1219 pOnuDeviceEntry := dh.pOnuOmciDevice
1220 if aWait && pOnuDeviceEntry == nil {
1221 //keep the read sema short to allow for subsequent write
1222 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001224 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1225 // so it might be needed to wait here for that event with some timeout
1226 select {
1227 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001229 return nil
1230 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001232 // if written now, we can return the written value without sema
1233 return dh.pOnuOmciDevice
1234 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001235 }
mpagenko3af1f032020-06-10 08:53:41 +00001236 dh.lockDevice.RUnlock()
1237 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001238}
1239
Himani Chawla6d2ae152020-09-02 13:11:20 +05301240//setOnuDeviceEntry sets the ONU device entry within the handler
1241func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001242 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001243 dh.lockDevice.Lock()
1244 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001245 dh.pOnuOmciDevice = apDeviceEntry
1246 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001247 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001248}
1249
Himani Chawla6d2ae152020-09-02 13:11:20 +05301250//addOnuDeviceEntry creates a new ONU device or returns the existing
1251func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001253
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001255 if deviceEntry == nil {
1256 /* costum_me_map in python code seems always to be None,
1257 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1258 /* also no 'clock' argument - usage open ...*/
1259 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001260 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001261 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001262 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001263 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001264 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001265 // fire deviceEntry ready event to spread to possibly waiting processing
1266 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001268 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001270 }
1271 // might be updated with some error handling !!!
1272 return nil
1273}
1274
dbainbri4d3a0dc2020-12-02 00:33:42 +00001275func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1276 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001277 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1278
1279 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001280
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001282 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001284 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1285 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001286 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001287 if err := dh.storePersistentData(ctx); err != nil {
1288 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001289 log.Fields{"device-id": dh.deviceID, "err": err})
1290 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001292 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001293 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001294 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1295 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001296 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001297 }
1298 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001299 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001300 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001301
1302 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 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 +00001304 log.Fields{"device-id": dh.deviceID})
1305 dh.reconciling = false
1306 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001307 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001308 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1309 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1310 // 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 +00001311 // 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 +00001312 // so let's just try to keep it simple ...
1313 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001315 if err != nil || device == nil {
1316 //TODO: needs to handle error scenarios
1317 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1318 return errors.New("Voltha Device not found")
1319 }
1320 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001321
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001323 return err
mpagenko3af1f032020-06-10 08:53:41 +00001324 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001325
dbainbri4d3a0dc2020-12-02 00:33:42 +00001326 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001327
1328 /* this might be a good time for Omci Verify message? */
1329 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001330 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001331 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001332 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001333 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001334
1335 /* give the handler some time here to wait for the OMCi verification result
1336 after Timeout start and try MibUpload FSM anyway
1337 (to prevent stopping on just not supported OMCI verification from ONU) */
1338 select {
1339 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001341 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001342 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001343 }
1344
1345 /* In py code it looks earlier (on activate ..)
1346 # Code to Run OMCI Test Action
1347 kwargs_omci_test_action = {
1348 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1349 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1350 }
1351 serial_number = device.serial_number
1352 self._test_request = OmciTestRequest(self.core_proxy,
1353 self.omci_agent, self.device_id,
1354 AniG, serial_number,
1355 self.logical_device_id,
1356 exclusive=False,
1357 **kwargs_omci_test_action)
1358 ...
1359 # Start test requests after a brief pause
1360 if not self._test_request_started:
1361 self._test_request_started = True
1362 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1363 reactor.callLater(tststart, self._test_request.start_collector)
1364
1365 */
1366 /* which is then: in omci_test_request.py : */
1367 /*
1368 def start_collector(self, callback=None):
1369 """
1370 Start the collection loop for an adapter if the frequency > 0
1371
1372 :param callback: (callable) Function to call to collect PM data
1373 """
1374 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1375 if callback is None:
1376 callback = self.perform_test_omci
1377
1378 if self.lc is None:
1379 self.lc = LoopingCall(callback)
1380
1381 if self.default_freq > 0:
1382 self.lc.start(interval=self.default_freq / 10)
1383
1384 def perform_test_omci(self):
1385 """
1386 Perform the initial test request
1387 """
1388 ani_g_entities = self._device.configuration.ani_g_entities
1389 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1390 is not None else None
1391 self._entity_id = ani_g_entities_ids[0]
1392 self.logger.info('perform-test', entity_class=self._entity_class,
1393 entity_id=self._entity_id)
1394 try:
1395 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1396 result = yield self._device.omci_cc.send(frame)
1397 if not result.fields['omci_message'].fields['success_code']:
1398 self.logger.info('Self-Test Submitted Successfully',
1399 code=result.fields[
1400 'omci_message'].fields['success_code'])
1401 else:
1402 raise TestFailure('Test Failure: {}'.format(
1403 result.fields['omci_message'].fields['success_code']))
1404 except TimeoutError as e:
1405 self.deferred.errback(failure.Failure(e))
1406
1407 except Exception as e:
1408 self.logger.exception('perform-test-Error', e=e,
1409 class_id=self._entity_class,
1410 entity_id=self._entity_id)
1411 self.deferred.errback(failure.Failure(e))
1412
1413 */
1414
1415 // PM related heartbeat??? !!!TODO....
1416 //self._heartbeat.enabled = True
1417
mpagenko1cc3cb42020-07-27 15:24:38 +00001418 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1419 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1420 * 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 +05301421 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001422 */
1423 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001424 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001425 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001426 if pMibUlFsm.Is(ulStDisabled) {
1427 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 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 +00001429 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301430 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301432 //Determine ONU status and start/re-start MIB Synchronization tasks
1433 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001434 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301435 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 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 +00001437 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001438 }
Himani Chawla4d908332020-08-31 12:30:20 +05301439 } else {
1440 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001441 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 +00001442 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301443 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001445 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001446 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001448 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001449 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001450 }
1451 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001452 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001453 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001455
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001456 if !dh.getCollectorIsRunning() {
1457 // Start PM collector routine
1458 go dh.startCollector(ctx)
1459 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001460 return nil
1461}
1462
dbainbri4d3a0dc2020-12-02 00:33:42 +00001463func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001464 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001465 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001466 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001468
mpagenko900ee4b2020-10-12 11:56:34 +00001469 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1470 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1471 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001472 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001473 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001474 log.Fields{"device-id": dh.deviceID, "error": err})
1475 // abort: system behavior is just unstable ...
1476 return err
1477 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001478 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 _ = 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 +00001480
1481 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1482 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1483 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001485 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001486 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001487 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001488 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001490
1491 //TODO!!! remove existing traffic profiles
1492 /* from py code, if TP's exist, remove them - not yet implemented
1493 self._tp = dict()
1494 # Let TP download happen again
1495 for uni_id in self._tp_service_specific_task:
1496 self._tp_service_specific_task[uni_id].clear()
1497 for uni_id in self._tech_profile_download_done:
1498 self._tech_profile_download_done[uni_id].clear()
1499 */
1500
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001502
mpagenkofc4f56e2020-11-04 17:17:49 +00001503 dh.ReadyForSpecificOmciConfig = false
1504
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001506 // abort: system behavior is just unstable ...
1507 return err
1508 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001510 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001511 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001512 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001513 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001515 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001516 // abort: system behavior is just unstable ...
1517 return err
1518 }
1519 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001521 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001522 return nil
1523}
1524
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001525func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001526 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1527 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1528 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1529 // and using the stop/reset event should never harm
1530
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001532 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001534 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1535 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001536 if includingMibSyncFsm {
1537 //the MibSync FSM might be active all the ONU-active time,
1538 // hence it must be stopped unconditionally
1539 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1540 if pMibUlFsm != nil {
1541 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1542 }
mpagenko900ee4b2020-10-12 11:56:34 +00001543 }
1544 //MibDownload may run
1545 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1546 if pMibDlFsm != nil {
1547 _ = pMibDlFsm.Event(dlEvReset)
1548 }
1549 //port lock/unlock FSM's may be active
1550 if dh.pUnlockStateFsm != nil {
1551 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1552 }
1553 if dh.pLockStateFsm != nil {
1554 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1555 }
1556 //techProfile related PonAniConfigFsm FSM may be active
1557 if dh.pOnuTP != nil {
1558 // should always be the case here
1559 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1560 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001561 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1562 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1563 }
mpagenko900ee4b2020-10-12 11:56:34 +00001564 }
1565 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001566 // reset the possibly existing VlanConfigFsm
1567 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1568 //VlanFilterFsm exists and was already started
1569 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1570 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001571 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001572 // no need to remove specific data
1573 pVlanFilterFsm.RequestClearPersistency(false)
1574 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001575 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1576 }
1577 }
1578 }
1579 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001580 if dh.getCollectorIsRunning() {
1581 // Stop collector routine
1582 dh.stopCollector <- true
1583 }
mpagenko900ee4b2020-10-12 11:56:34 +00001584 return nil
1585}
1586
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1588 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 +05301589
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1591 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001592 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001593 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001594 return
1595 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001596 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001597 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1598 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1599 for _, mgmtEntityID := range pptpInstKeys {
1600 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1601 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301603 i++
1604 }
1605 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301607 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001608 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1609 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301610 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001611 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301612 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301614 i++
1615 }
1616 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301618 }
1619 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301621 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001622 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1623 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1624 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1625 * disable/enable toggling here to allow traffic
1626 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1627 * like the py comment says:
1628 * # start by locking all the unis till mib sync and initial mib is downloaded
1629 * # this way we can capture the port down/up events when we are ready
1630 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301631
mpagenkoa40e99a2020-11-17 13:50:39 +00001632 // Init Uni Ports to Admin locked state
1633 // *** should generate UniLockStateDone event *****
1634 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001636 } else { //LockStateFSM already init
1637 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001639 }
1640}
1641
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1643 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301644 /* Mib download procedure -
1645 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1646 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001648 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001650 return
1651 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301652 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1653 if pMibDlFsm != nil {
1654 if pMibDlFsm.Is(dlStDisabled) {
1655 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 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 +05301657 // maybe try a FSM reset and then again ... - TODO!!!
1658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301660 // maybe use more specific states here for the specific download steps ...
1661 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301665 //Begin MIB data download (running autonomously)
1666 }
1667 }
1668 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001670 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301671 // maybe try a FSM reset and then again ... - TODO!!!
1672 }
1673 /***** Mib download started */
1674 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 }
1677}
1678
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1680 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301681 //initiate DevStateUpdate
1682 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001684 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301686 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1687 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301689 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301691 }
1692 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001696 return
1697 }
1698 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001699 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked and wait for re-enabling",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001700 log.Fields{"device-id": dh.deviceID})
1701 dh.reconciling = false
1702 return
1703 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301705 log.Fields{"device-id": dh.deviceID})
1706 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
Girish Gowdrae0140f02021-02-02 16:55:09 -08001708
1709 // Initialize classical L2 PM Interval Counters
1710 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1711 // There is no way we should be landing here, but if we do then
1712 // there is nothing much we can do about this other than log error
1713 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1714 }
1715
mpagenkofc4f56e2020-11-04 17:17:49 +00001716 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301717 // *** should generate UniUnlockStateDone event *****
1718 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301720 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301721 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301723 }
1724}
1725
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1727 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301728
1729 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301731 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1733 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001734 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001736 return
1737 }
1738 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 if err := dh.storePersistentData(ctx); err != nil {
1740 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001741 log.Fields{"device-id": dh.deviceID, "err": err})
1742 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301743 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 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 +05301745 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001747 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301748 }
1749}
1750
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1752 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001753 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001755 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1756 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001758 }
1759
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001761 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001763
1764 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001766
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001768 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001770 return
1771 }
1772 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 if err := dh.storePersistentData(ctx); err != nil {
1774 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001775 log.Fields{"device-id": dh.deviceID, "err": err})
1776 }
mpagenko900ee4b2020-10-12 11:56:34 +00001777}
1778
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1780 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001781 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001783 voltha.OperStatus_ACTIVE); err != nil {
1784 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001786 }
1787
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001790 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001792
1793 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001795
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001797 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001799 return
1800 }
1801 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 if err := dh.storePersistentData(ctx); err != nil {
1803 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001804 log.Fields{"device-id": dh.deviceID, "err": err})
1805 }
mpagenko900ee4b2020-10-12 11:56:34 +00001806}
1807
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001809 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001811 // attention: the device reason update is done based on ONU-UNI-Port related activity
1812 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001813 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001814 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301816 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001817 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001819 }
1820 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001822 // attention: the device reason update is done based on ONU-UNI-Port related activity
1823 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001824 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001825 // 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 +00001826 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001827 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001828 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301829}
1830
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1832 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001833 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301834 // attention: the device reason update is done based on ONU-UNI-Port related activity
1835 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301836
mpagenkofc4f56e2020-11-04 17:17:49 +00001837 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001838 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001839 // which may be the case from some previous actvity on another UNI Port of the ONU
1840 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001842 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001844 }
1845 }
1846 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001847 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001848 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001850 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301851 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001852 if err := dh.storePersistentData(ctx); err != nil {
1853 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1854 log.Fields{"device-id": dh.deviceID, "err": err})
1855 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301856}
1857
Himani Chawla6d2ae152020-09-02 13:11:20 +05301858//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301860 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001861 case MibDatabaseSync:
1862 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001864 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001865 case UniLockStateDone:
1866 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001868 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001869 case MibDownloadDone:
1870 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001872 }
1873 case UniUnlockStateDone:
1874 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001876 }
mpagenko900ee4b2020-10-12 11:56:34 +00001877 case UniEnableStateDone:
1878 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001880 }
1881 case UniDisableStateDone:
1882 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001884 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001885 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001886 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001888 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001889 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001890 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001892 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001893 default:
1894 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001896 }
1897 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001898}
1899
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001901 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301903 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001904 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001906 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301907 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001909 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001911 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001912 //store UniPort with the System-PortNumber key
1913 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001914 if !dh.reconciling {
1915 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1917 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001918 } //error logging already within UniPort method
1919 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001921 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001922 }
1923 }
1924}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001925
mpagenko3af1f032020-06-10 08:53:41 +00001926// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001928 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301929 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001930 // with following remark:
1931 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1932 // # load on the core
1933
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001934 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001935
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001936 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001937 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301938 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301940 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001941 if !dh.reconciling {
1942 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 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 +00001944 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001945 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001947 }
mpagenko3af1f032020-06-10 08:53:41 +00001948 }
1949 }
1950}
1951
1952// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001954 // compare enableUniPortStateUpdate() above
1955 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1956 for uniNo, uniPort := range dh.uniEntityMap {
1957 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301958 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301960 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001961 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001963 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001964 }
1965}
1966
1967// ONU_Active/Inactive announcement on system KAFKA bus
1968// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001970 var de voltha.DeviceEvent
1971 eventContext := make(map[string]string)
1972 //Populating event context
1973 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001975 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301977 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001978 }
1979 oltSerialNumber := parentDevice.SerialNumber
1980
1981 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1982 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1983 eventContext["serial-number"] = dh.device.SerialNumber
1984 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301985 eventContext["device_id"] = aDeviceID
1986 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001988 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001989
1990 /* Populating device event body */
1991 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301992 de.ResourceId = aDeviceID
1993 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001994 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1995 de.Description = fmt.Sprintf("%s Event - %s - %s",
1996 cEventObjectType, cOnuActivatedEvent, "Raised")
1997 } else {
1998 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1999 de.Description = fmt.Sprintf("%s Event - %s - %s",
2000 cEventObjectType, cOnuActivatedEvent, "Cleared")
2001 }
2002 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2004 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302005 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002006 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302008 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002009}
2010
Himani Chawla4d908332020-08-31 12:30:20 +05302011// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002012func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002013 chLSFsm := make(chan Message, 2048)
2014 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302015 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002017 sFsmName = "LockStateFSM"
2018 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002020 sFsmName = "UnLockStateFSM"
2021 }
mpagenko3af1f032020-06-10 08:53:41 +00002022
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002024 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002026 return
2027 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002028 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002029 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002030 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302031 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002032 dh.pLockStateFsm = pLSFsm
2033 } else {
2034 dh.pUnlockStateFsm = pLSFsm
2035 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002037 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002038 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002039 }
2040}
2041
2042// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002044 /* Uni Port lock/unlock procedure -
2045 ***** should run via 'adminDone' state and generate the argument requested event *****
2046 */
2047 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302048 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002049 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2050 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2051 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002052 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302053 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002054 }
2055 } else {
2056 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2057 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2058 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002059 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302060 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002061 }
2062 }
2063 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002064 if pLSStatemachine.Is(uniStDisabled) {
2065 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002067 // maybe try a FSM reset and then again ... - TODO!!!
2068 } else {
2069 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002071 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002072 }
2073 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002075 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002076 // maybe try a FSM reset and then again ... - TODO!!!
2077 }
2078 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002080 // maybe try a FSM reset and then again ... - TODO!!!
2081 }
2082}
2083
Himani Chawla6d2ae152020-09-02 13:11:20 +05302084//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002085func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002086
2087 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002088 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002089 kvbackend := &db.Backend{
2090 Client: dh.pOpenOnuAc.kvClient,
2091 StoreType: dh.pOpenOnuAc.KVStoreType,
2092 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002093 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002094 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2095 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002096
mpagenkoaf801632020-07-03 10:00:42 +00002097 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002098}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002099func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302100 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002101
mpagenkodff5dda2020-08-28 11:52:01 +00002102 for _, field := range flow.GetOfbFields(apFlowItem) {
2103 switch field.Type {
2104 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2105 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002106 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002107 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2108 }
mpagenko01e726e2020-10-23 09:45:29 +00002109 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002110 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2111 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302112 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002113 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302114 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2115 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002116 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2117 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002118 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2119 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302120 return
mpagenkodff5dda2020-08-28 11:52:01 +00002121 }
2122 }
mpagenko01e726e2020-10-23 09:45:29 +00002123 */
mpagenkodff5dda2020-08-28 11:52:01 +00002124 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2125 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302126 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002127 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302128 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002129 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302130 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002131 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302133 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002134 }
2135 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2136 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302137 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002139 "PCP": loAddPcp})
2140 }
2141 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2142 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002143 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002144 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2145 }
2146 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2147 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002149 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2150 }
2151 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2152 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002154 "IPv4-DST": field.GetIpv4Dst()})
2155 }
2156 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2157 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002159 "IPv4-SRC": field.GetIpv4Src()})
2160 }
2161 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2162 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002164 "Metadata": field.GetTableMetadata()})
2165 }
2166 /*
2167 default:
2168 {
2169 //all other entires ignored
2170 }
2171 */
2172 }
2173 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302174}
mpagenkodff5dda2020-08-28 11:52:01 +00002175
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002177 for _, action := range flow.GetActions(apFlowItem) {
2178 switch action.Type {
2179 /* not used:
2180 case of.OfpActionType_OFPAT_OUTPUT:
2181 {
mpagenko01e726e2020-10-23 09:45:29 +00002182 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002183 "Output": action.GetOutput()})
2184 }
2185 */
2186 case of.OfpActionType_OFPAT_PUSH_VLAN:
2187 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002189 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2190 }
2191 case of.OfpActionType_OFPAT_SET_FIELD:
2192 {
2193 pActionSetField := action.GetSetField()
2194 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002196 "OxcmClass": pActionSetField.Field.OxmClass})
2197 }
2198 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302199 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302201 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002202 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302205 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002206 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002208 "Type": pActionSetField.Field.GetOfbField().Type})
2209 }
2210 }
2211 /*
2212 default:
2213 {
2214 //all other entires ignored
2215 }
2216 */
2217 }
2218 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302219}
2220
2221//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302223 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2224 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2225 var loAddPcp, loSetPcp uint8
2226 var loIPProto uint32
2227 /* the TechProfileId is part of the flow Metadata - compare also comment within
2228 * OLT-Adapter:openolt_flowmgr.go
2229 * Metadata 8 bytes:
2230 * Most Significant 2 Bytes = Inner VLAN
2231 * Next 2 Bytes = Tech Profile ID(TPID)
2232 * Least Significant 4 Bytes = Port ID
2233 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2234 * subscriber related flows.
2235 */
2236
dbainbri4d3a0dc2020-12-02 00:33:42 +00002237 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302238 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002239 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302240 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002241 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302242 }
mpagenko551a4d42020-12-08 18:09:20 +00002243 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002244 loCookie := apFlowItem.GetCookie()
2245 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002247 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302248
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002250 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302251 if loIPProto == 2 {
2252 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2253 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002254 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2255 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302256 return nil
2257 }
mpagenko01e726e2020-10-23 09:45:29 +00002258 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002260
2261 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002263 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2264 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2265 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2266 //TODO!!: Use DeviceId within the error response to rwCore
2267 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002268 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002269 }
2270 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002271 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002272 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2273 } else {
2274 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2275 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2276 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302277 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002278 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002279 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002280 }
mpagenko9a304ea2020-12-16 15:54:01 +00002281
2282 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2283 dh.lockVlanConfig.Lock()
2284 defer dh.lockVlanConfig.Unlock()
2285 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302286 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002288 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002289 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002291 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002292}
2293
2294//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002295func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002296 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2297 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2298 //no extra check is done on the rule parameters
2299 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2300 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2301 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2302 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002303 // - 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 +00002304 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002305 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002306
2307 /* TT related temporary workaround - should not be needed anymore
2308 for _, field := range flow.GetOfbFields(apFlowItem) {
2309 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2310 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002311 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002312 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2313 if loIPProto == 2 {
2314 // 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 +00002315 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002316 log.Fields{"device-id": dh.deviceID})
2317 return nil
2318 }
2319 }
2320 } //for all OfbFields
2321 */
2322
mpagenko9a304ea2020-12-16 15:54:01 +00002323 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2324 dh.lockVlanConfig.Lock()
2325 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002326 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002328 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002330 log.Fields{"device-id": dh.deviceID})
2331 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002332 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002334
mpagenko01e726e2020-10-23 09:45:29 +00002335 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002336}
2337
Himani Chawla26e555c2020-08-31 12:30:20 +05302338// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002339// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002340func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002341 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002342 chVlanFilterFsm := make(chan Message, 2048)
2343
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002345 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302347 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002348 }
2349
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002351 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2352 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002353 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302354 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002355 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2356 if pVlanFilterStatemachine != nil {
2357 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2358 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002359 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302360 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002361 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302362 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302364 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2365 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002366 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002367 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002368 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002370 }
2371 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002372 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002373 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002375 }
2376 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002377 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002378 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002380 }
2381 return nil
2382}
2383
mpagenkofc4f56e2020-11-04 17:17:49 +00002384//VerifyVlanConfigRequest checks on existence of a given uniPort
2385// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002386func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002387 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2388 var pCurrentUniPort *onuUniPort
2389 for _, uniPort := range dh.uniEntityMap {
2390 // only if this port is validated for operState transfer
2391 if uniPort.uniID == uint8(aUniID) {
2392 pCurrentUniPort = uniPort
2393 break //found - end search loop
2394 }
2395 }
2396 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002397 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002398 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2399 return
2400 }
mpagenko551a4d42020-12-08 18:09:20 +00002401 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002402}
2403
mpagenkodff5dda2020-08-28 11:52:01 +00002404//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002405func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002406 //TODO!! verify and start pending flow configuration
2407 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2408 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002410 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2411 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2412 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002413 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2414 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2415 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2416 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2417 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2418 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2419 } else {
2420 /***** UniVlanConfigFsm continued */
2421 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2422 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2423 "UniPort": apUniPort.portNo})
2424 }
2425 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2426 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2427 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2428 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2429 } else {
2430 /***** UniVlanConfigFsm continued */
2431 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2432 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2433 "UniPort": apUniPort.portNo})
2434 }
mpagenkodff5dda2020-08-28 11:52:01 +00002435 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002436 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2437 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002438 "UniPort": apUniPort.portNo})
2439 }
2440 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002441 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2442 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2443 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002444 }
2445 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002446 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002447 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002448 }
mpagenkodff5dda2020-08-28 11:52:01 +00002449 } // else: nothing to do
2450}
2451
2452//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2453// 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 +00002454func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2455 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002456 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2457 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302458 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002459}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002460
Girish Gowdra26a40922021-01-29 17:14:34 -08002461//ProcessPendingTpDelete processes any pending TP delete (if available)
2462func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2463 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2464 if apUniPort == nil {
2465 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2466 return
2467 }
2468 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2469 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2470 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2471 if pAniConfigStatemachine != nil {
2472 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2473 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2474 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2475 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2476 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2477 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2478 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2479 return
2480 }
2481 } else {
2482 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2483 return
2484 }
2485 }
2486 return
2487 }
2488}
2489
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002490//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2491//available for potential reconcilement
2492
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002494
2495 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002497 return nil
2498 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002500
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002502 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002503 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002504 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2505 }
2506 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2507
2508 pDevEntry.lockOnuKVStoreMutex()
2509 defer pDevEntry.unlockOnuKVStoreMutex()
2510
2511 // deadline context to ensure completion of background routines waited for
2512 //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 +05302513 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002514 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2515
2516 pDevEntry.resetKvProcessingErrorIndication()
2517 var wg sync.WaitGroup
2518 wg.Add(1) // for the 1 go routine to finish
2519
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2521 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002522
2523 return pDevEntry.getKvProcessingErrorIndication()
2524}
2525
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002527 defer cancel() //ensure termination of context (may be pro forma)
2528 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002530 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002531}
2532
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002534
2535 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002536 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002537 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002538 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2539 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002540 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002541 return err
2542 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002543 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002544 return nil
2545 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002547 return nil
2548}
2549
dbainbri4d3a0dc2020-12-02 00:33:42 +00002550func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2551 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002552 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002554 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2555 }
2556 pDevEntry.lockOnuKVStoreMutex()
2557 defer pDevEntry.unlockOnuKVStoreMutex()
2558
2559 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2560 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2561
2562 pDevEntry.resetKvProcessingErrorIndication()
2563 var wg sync.WaitGroup
2564 wg.Add(1) // for the 1 go routine to finish
2565
2566 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002567 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002568
2569 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002571 return err
2572 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002573 return nil
2574}
2575
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002576func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2577 var errStr string = ""
2578 for _, err := range errS {
2579 if err != nil {
2580 errStr = errStr + err.Error() + " "
2581 }
2582 }
2583 if errStr != "" {
2584 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2585 }
2586 return nil
2587}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002588
2589// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2590func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2591 dh.lockDevice.RLock()
2592 defer dh.lockDevice.RUnlock()
2593 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2594 return uniPort.entityID, nil
2595 }
2596 return 0, errors.New("error-fetching-uni-port")
2597}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002598
2599// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002600func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2601 var errorsList []error
2602 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 -08002603
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002604 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2605 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2606 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2607
2608 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2609 // successfully.
2610 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2611 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2612 if len(errorsList) > 0 {
2613 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2614 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002615 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002616 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2617 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002618}
2619
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002620func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2621 var err error
2622 var errorsList []error
2623 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2624
2625 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2626 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2627 errorsList = append(errorsList, err)
2628 }
2629 }
2630
2631 return errorsList
2632}
2633
2634func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2635 var err error
2636 var errorsList []error
2637 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2638 // Check if group metric related config is updated
2639 for _, v := range pmConfigs.Groups {
2640 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2641 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2642 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2643
2644 if ok && m.frequency != v.GroupFreq {
2645 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2646 errorsList = append(errorsList, err)
2647 }
2648 }
2649 if ok && m.enabled != v.Enabled {
2650 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2651 errorsList = append(errorsList, err)
2652 }
2653 }
2654 }
2655 return errorsList
2656}
2657
2658func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2659 var err error
2660 var errorsList []error
2661 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2662 // Check if standalone metric related config is updated
2663 for _, v := range pmConfigs.Metrics {
2664 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002665 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002666 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2667
2668 if ok && m.frequency != v.SampleFreq {
2669 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2670 errorsList = append(errorsList, err)
2671 }
2672 }
2673 if ok && m.enabled != v.Enabled {
2674 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2675 errorsList = append(errorsList, err)
2676 }
2677 }
2678 }
2679 return errorsList
2680}
2681
2682// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002683func (dh *deviceHandler) startCollector(ctx context.Context) {
2684 logger.Debugf(ctx, "startingCollector")
2685
2686 // Start routine to process OMCI GET Responses
2687 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002688 // Initialize the next metric collection time.
2689 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2690 // reset like onu rebooted.
2691 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002692 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002693 for {
2694 select {
2695 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002696 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002697 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002698 // Stop the L2 PM FSM
2699 go func() {
2700 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2701 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2702 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2703 }
2704 } else {
2705 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2706 }
2707 }()
2708
Girish Gowdrae09a6202021-01-12 18:10:59 -08002709 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002710 dh.pOnuMetricsMgr.stopTicks <- true
2711
Girish Gowdrae09a6202021-01-12 18:10:59 -08002712 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002713 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2714 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2715 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2716 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2717 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002718 // Update the next metric collection time.
2719 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002720 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002721 } else {
2722 if dh.pmConfigs.Grouped { // metrics are managed as a group
2723 // parse through the group and standalone metrics to see it is time to collect their metrics
2724 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002725
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002726 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2727 // 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 -08002728 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2729 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002730 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2731 }
2732 }
2733 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2734 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2735 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2736 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2737 }
2738 }
2739 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2740
2741 // parse through the group and update the next metric collection time
2742 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2743 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2744 // 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 -08002745 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2746 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002747 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2748 }
2749 }
2750 // parse through the standalone metrics and update the next metric collection time
2751 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2752 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2753 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2754 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2755 }
2756 }
2757 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2758 } /* else { // metrics are not managed as a group
2759 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2760 } */
2761 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002762 }
2763 }
2764}
kesavandfdf77632021-01-26 23:40:33 -05002765
2766func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2767
2768 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2769 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2770}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002771
2772func (dh *deviceHandler) isFsmInState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2773 var currentState string
2774 if pFsm != nil {
2775 currentState = pFsm.Current()
2776 if currentState == wantedState {
2777 return true
2778 }
2779 } else {
2780 logger.Warnw(ctx, "FSM not defined!", log.Fields{"wantedState": wantedState, "device-id": dh.deviceID})
2781 }
2782 return false
2783}
2784
2785func (dh *deviceHandler) mibUploadFsmInIdleState(ctx context.Context, idleState string) bool {
2786 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibUploadFsm.pFsm, idleState)
2787}
2788
2789func (dh *deviceHandler) mibDownloadFsmInIdleState(ctx context.Context, idleState string) bool {
2790 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibDownloadFsm.pFsm, idleState)
2791}
2792
2793func (dh *deviceHandler) devUniLockFsmInIdleState(ctx context.Context, idleState string) bool {
2794 return dh.isFsmInState(ctx, dh.pLockStateFsm.pAdaptFsm.pFsm, idleState)
2795}
2796
2797func (dh *deviceHandler) devUniUnlockFsmInIdleState(ctx context.Context, idleState string) bool {
2798 return dh.isFsmInState(ctx, dh.pUnlockStateFsm.pAdaptFsm.pFsm, idleState)
2799}
2800
2801func (dh *deviceHandler) devAniConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2802 if dh.pOnuTP.pAniConfigFsm != nil {
2803 for _, v := range dh.pOnuTP.pAniConfigFsm {
2804 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2805 return false
2806 }
2807 }
2808 return true
2809 }
2810 logger.Warnw(ctx, "AniConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2811 return false
2812}
2813
2814func (dh *deviceHandler) devUniVlanConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2815 if dh.UniVlanConfigFsmMap != nil {
2816 for _, v := range dh.UniVlanConfigFsmMap {
2817 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2818 return false
2819 }
2820 }
2821 return true
2822 }
2823 logger.Warnw(ctx, "UniVlanConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2824 return false
2825}
2826
Girish Gowdrae0140f02021-02-02 16:55:09 -08002827func (dh *deviceHandler) l2PmFsmInIdleState(ctx context.Context, idleState string) bool {
2828 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2829 return dh.isFsmInState(ctx, dh.pOnuMetricsMgr.pAdaptFsm.pFsm, idleState)
2830 }
2831 logger.Warnw(ctx, "L2 PM FSM not defined!", log.Fields{"device-id": dh.deviceID})
2832 return false
2833}
2834
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002835func (dh *deviceHandler) allButCallingFsmInIdleState(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
2836 for fsmName, fsmStruct := range fsmIdleStateFuncMap {
2837 if fsmName != callingFsm && !fsmStruct.idleCheckFunc(dh, ctx, fsmStruct.idleState) {
2838 return false
2839 }
2840 }
2841 return true
2842}
2843
2844func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
2845 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
2846 if err := dh.resetFsms(ctx, false); err != nil {
2847 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
2848 // TODO: fatal error reset ONU, delete deviceHandler!
2849 return
2850 }
2851 if !dh.getCollectorIsRunning() {
2852 // Start PM collector routine
2853 go dh.startCollector(ctx)
2854 }
2855 dh.uniEntityMap = make(map[uint32]*onuUniPort)
2856 dh.reconciling = true
2857}
2858
2859func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
2860 dh.mutexCollectorFlag.Lock()
2861 dh.collectorIsRunning = flagValue
2862 dh.mutexCollectorFlag.Unlock()
2863}
2864
2865func (dh *deviceHandler) getCollectorIsRunning() bool {
2866 dh.mutexCollectorFlag.RLock()
2867 flagValue := dh.collectorIsRunning
2868 dh.mutexCollectorFlag.RUnlock()
2869 return flagValue
2870}