blob: 379afa873a03743ac70d96baae3ae4e951d8392a [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()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367
368 if techProfMsg.UniId > 255 {
369 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
370 techProfMsg.UniId, dh.deviceID))
371 }
372 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
374 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800376 return err
377 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 // if there has been some change for some uni TechProfilePath
381 //in order to allow concurrent calls to other dh instances we do not wait for execution here
382 //but doing so we can not indicate problems to the caller (who does what with that then?)
383 //by now we just assume straightforward successful execution
384 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
385 // possible problems to the caller later autonomously
386
387 // deadline context to ensure completion of background routines waited for
388 //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 +0530389 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 dctx, cancel := context.WithDeadline(context.Background(), deadline)
391
Girish Gowdra041dcb32020-11-16 16:54:30 -0800392 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 pDevEntry.resetKvProcessingErrorIndication()
394
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 var wg sync.WaitGroup
396 wg.Add(2) // for the 2 go routines to finish
397 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
399 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
400 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
Girish Gowdra041dcb32020-11-16 16:54:30 -0800402 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 return nil
406}
407
Himani Chawla6d2ae152020-09-02 13:11:20 +0530408func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000409 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 msg *ic.InterAdapterMessage) error {
411
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000413
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
418 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 if dh.pOnuTP == nil {
420 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 }
425
426 msgBody := msg.GetBody()
427 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
428 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530430 "device-id": dh.deviceID, "error": err})
431 return err
432 }
433
434 //compare TECH_PROFILE_DOWNLOAD_REQUEST
435 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530437
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000438 if delGemPortMsg.UniId > 255 {
439 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
440 delGemPortMsg.UniId, dh.deviceID))
441 }
442 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800443 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
444 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000445 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 -0800446 return err
447 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530448
mpagenkofc4f56e2020-11-04 17:17:49 +0000449 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450
mpagenkofc4f56e2020-11-04 17:17:49 +0000451 // deadline context to ensure completion of background routines waited for
452 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
453 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000454
Girish Gowdra041dcb32020-11-16 16:54:30 -0800455 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456
mpagenkofc4f56e2020-11-04 17:17:49 +0000457 var wg sync.WaitGroup
458 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000460 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000462
Girish Gowdra041dcb32020-11-16 16:54:30 -0800463 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530464}
465
Himani Chawla6d2ae152020-09-02 13:11:20 +0530466func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000467 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530468 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000471
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000473 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000475 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
476 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 if dh.pOnuTP == nil {
478 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 }
483
484 msgBody := msg.GetBody()
485 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
486 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 "device-id": dh.deviceID, "error": err})
489 return err
490 }
491
492 //compare TECH_PROFILE_DOWNLOAD_REQUEST
493 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495
496 if delTcontMsg.UniId > 255 {
497 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
498 delTcontMsg.UniId, dh.deviceID))
499 }
500 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800501 tpPath := delTcontMsg.TpPath
502 tpID, err := GetTpIDFromTpPath(tpPath)
503 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000504 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 return err
506 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530509 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530510 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530511 dctx, cancel := context.WithDeadline(context.Background(), deadline)
512
Girish Gowdra041dcb32020-11-16 16:54:30 -0800513 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514 pDevEntry.resetKvProcessingErrorIndication()
515
Himani Chawla26e555c2020-08-31 12:30:20 +0530516 var wg sync.WaitGroup
517 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000518 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530519 cResourceTcont, delTcontMsg.AllocId, &wg)
520 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
522 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523
Girish Gowdra041dcb32020-11-16 16:54:30 -0800524 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530525 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 return nil
527}
528
Himani Chawla6d2ae152020-09-02 13:11:20 +0530529//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000530// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
531// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000532func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000533 msgID := msg.Header.Id
534 msgType := msg.Header.Type
535 fromTopic := msg.Header.FromTopic
536 toTopic := msg.Header.ToTopic
537 toDeviceID := msg.Header.ToDeviceId
538 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000540 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
541
542 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000543 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000544 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
545 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000546 {
mpagenko057889c2021-01-21 16:51:58 +0000547 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000548 }
mpagenkoaf801632020-07-03 10:00:42 +0000549 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
550 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000552 }
553 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
554 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000556
mpagenkoaf801632020-07-03 10:00:42 +0000557 }
558 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
559 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000560 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000561 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000562 default:
563 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000565 "msgType": msg.Header.Type, "device-id": dh.deviceID})
566 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000567 }
568 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000569}
570
mpagenkodff5dda2020-08-28 11:52:01 +0000571//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
573 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000574 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000576
mpagenko01e726e2020-10-23 09:45:29 +0000577 var retError error = nil
578 //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 +0000579 if apOfFlowChanges.ToRemove != nil {
580 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000581 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000582 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000583 "device-id": dh.deviceID})
584 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000585 continue
586 }
587 flowInPort := flow.GetInPort(flowItem)
588 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 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 +0000590 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
591 continue
592 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000593 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000594 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000595 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000596 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000597 continue
598 } else {
599 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530600 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000601 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
602 loUniPort = uniPort
603 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000605 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
606 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
607 flowInPort, dh.deviceID)
608 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000609 }
610 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000612 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000613 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000615 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000616 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000618 log.Fields{"device-id": dh.deviceID, "error": err})
619 retError = err
620 continue
621 //return err
622 } else { // if last setting succeeds, overwrite possibly previously set error
623 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000624 }
625 }
626 }
627 }
mpagenko01e726e2020-10-23 09:45:29 +0000628 if apOfFlowChanges.ToAdd != nil {
629 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
630 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000632 "device-id": dh.deviceID})
633 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
634 continue
635 }
636 flowInPort := flow.GetInPort(flowItem)
637 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638 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 +0000639 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
640 continue
641 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
642 } else if flowInPort == dh.ponPortNumber {
643 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000645 "device-id": dh.deviceID, "inPort": flowInPort})
646 continue
647 } else {
648 // this is the relevant upstream flow
649 var loUniPort *onuUniPort
650 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
651 loUniPort = uniPort
652 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000654 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
655 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
656 flowInPort, dh.deviceID)
657 continue
658 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
659 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000660 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
661 // if not, we just throw some error here to have an indication about that, if we really need to support that
662 // then we would need to create some means to activate the internal stored flows
663 // after the device gets active automatically (and still with its dependency to the TechProfile)
664 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
665 // also abort for the other still possible flows here
666 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000667 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000668 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000669 return fmt.Errorf("improper device state on device %s", dh.deviceID)
670 }
671
mpagenko01e726e2020-10-23 09:45:29 +0000672 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000674 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
675 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000677 //try next flow after processing error
678 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000680 log.Fields{"device-id": dh.deviceID, "error": err})
681 retError = err
682 continue
683 //return err
684 } else { // if last setting succeeds, overwrite possibly previously set error
685 retError = nil
686 }
687 }
688 }
689 }
690 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000691}
692
Himani Chawla6d2ae152020-09-02 13:11:20 +0530693//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000694//following are the expected device states after this activity:
695//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
696// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
698 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000699
mpagenko900ee4b2020-10-12 11:56:34 +0000700 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000701 //note that disableDevice sequences in some 'ONU active' state may yield also
702 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000703 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000704 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000705 //disable-device shall be just a UNi/ONU-G related admin state setting
706 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000707
mpagenkofc4f56e2020-11-04 17:17:49 +0000708 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000709 // disable UNI ports/ONU
710 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
711 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000713 } else { //LockStateFSM already init
714 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000716 }
717 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000719 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000721 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
722 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000724 }
mpagenko01e726e2020-10-23 09:45:29 +0000725 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000726
727 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000729 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300730 }
731}
732
Himani Chawla6d2ae152020-09-02 13:11:20 +0530733//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
735 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000736
mpagenkofc4f56e2020-11-04 17:17:49 +0000737 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
738 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
739 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
740 // for real ONU's that should have nearly no influence
741 // Note that for real ONU's there is anyway a problematic situation with following sequence:
742 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
743 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
744 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
745 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
746
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000747 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000748 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000749 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000751 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000752 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000754 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300755}
756
dbainbri4d3a0dc2020-12-02 00:33:42 +0000757func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
758 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000759
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000761 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000763 return
764 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000766 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000767 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000768 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000770 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000771 dh.reconciling = false
772 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000773 }
Himani Chawla4d908332020-08-31 12:30:20 +0530774 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000775 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
776 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
777 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
778 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000780}
781
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
783 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000784
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000786 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000788 return
789 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790 dh.pOnuTP.lockTpProcMutex()
791 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000792 pDevEntry.persUniConfigMutex.RLock()
793 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000795 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000797 log.Fields{"device-id": dh.deviceID})
798 dh.reconciling = false
799 return
800 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000801 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000802 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
803 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000805 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
806 dh.reconciling = false
807 return
808 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800809 for tpID := range uniData.PersTpPathMap {
810 // deadline context to ensure completion of background routines waited for
811 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
812 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000814
Girish Gowdra041dcb32020-11-16 16:54:30 -0800815 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
816 var wg sync.WaitGroup
817 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
819 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800820 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800822 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000823 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000824 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000826 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
827 dh.reconciling = false
828 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000829 }
830}
831
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
833 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000834
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000838 return
839 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000840 pDevEntry.persUniConfigMutex.RLock()
841 defer pDevEntry.persUniConfigMutex.RUnlock()
842
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000843 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000845 log.Fields{"device-id": dh.deviceID})
846 dh.reconciling = false
847 return
848 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000849 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000850 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
851 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000853 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
854 dh.reconciling = false
855 return
856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 var uniPort *onuUniPort
858 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000862 return
863 }
864 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000866 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000867 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000869 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
870 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000873 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000875 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000876 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878 }
879 }
880 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000881 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000882 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
884 dh.reconciling = false
885 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000886 }
887}
888
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
890 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 +0000891
892 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000893 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000894}
895
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
897 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000900 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000901 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000903 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000904 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905
906 // deadline context to ensure completion of background routines waited for
907 //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 +0530908 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000909 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000910
911 pDevEntry.resetKvProcessingErrorIndication()
912
913 var wg sync.WaitGroup
914 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000915 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
916 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000917
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000918 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000919 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000920}
921
dbainbri4d3a0dc2020-12-02 00:33:42 +0000922func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
923 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300924 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000926 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300927 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530929 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530931 return err
932 }
mpagenko01e726e2020-10-23 09:45:29 +0000933
934 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000935 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000936
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000938 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300940 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000941 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300943 return err
944 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300946 return err
947 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000948 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000949 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
950 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
951 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
952 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300953 return nil
954}
955
mpagenkoc8bba412021-01-15 15:38:44 +0000956//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
957func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
958 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
959 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000960 //return success to comfort the core processing during integration
961 return nil
962 // TODO!!: also verify error response behavior
963 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000964}
965
Himani Chawla6d2ae152020-09-02 13:11:20 +0530966// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000967// #####################################################################################
968
969// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530970// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000971
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
973 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 +0000974}
975
976// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000978
dbainbri4d3a0dc2020-12-02 00:33:42 +0000979 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000980 var err error
981
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000982 // populate what we know. rest comes later after mib sync
983 dh.device.Root = false
984 dh.device.Vendor = "OpenONU"
985 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000986 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000987 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000988
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000989 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000990
991 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
993 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530994 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000995 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000997 log.Fields{"device-id": dh.deviceID})
998 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000999
Himani Chawla4d908332020-08-31 12:30:20 +05301000 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001001 dh.ponPortNumber = dh.device.ParentPortNo
1002
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001003 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1004 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1005 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001007 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301008 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001009
1010 /*
1011 self._pon = PonPort.create(self, self._pon_port_number)
1012 self._pon.add_peer(self.parent_id, self._pon_port_number)
1013 self.logger.debug('adding-pon-port-to-agent',
1014 type=self._pon.get_port().type,
1015 admin_state=self._pon.get_port().admin_state,
1016 oper_status=self._pon.get_port().oper_status,
1017 )
1018 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001019 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001021 var ponPortNo uint32 = 1
1022 if dh.ponPortNumber != 0 {
1023 ponPortNo = dh.ponPortNumber
1024 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001025
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001026 pPonPort := &voltha.Port{
1027 PortNo: ponPortNo,
1028 Label: fmt.Sprintf("pon-%d", ponPortNo),
1029 Type: voltha.Port_PON_ONU,
1030 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301031 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001032 PortNo: ponPortNo}}, // Peer port is parent's port number
1033 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001034 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1035 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001036 e.Cancel(err)
1037 return
1038 }
1039 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001040 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001041 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001042 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001043}
1044
1045// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001047
dbainbri4d3a0dc2020-12-02 00:33:42 +00001048 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001049 var err error
1050 /*
1051 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1052 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1053 return nil
1054 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1056 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001057 e.Cancel(err)
1058 return
1059 }
1060
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001061 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001062 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001063 // reconcilement will be continued after mib download is done
1064 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001065
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001066 /*
1067 ############################################################################
1068 # Setup Alarm handler
1069 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1070 device.serial_number)
1071 ############################################################################
1072 # Setup PM configuration for this device
1073 # Pass in ONU specific options
1074 kwargs = {
1075 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1076 'heartbeat': self.heartbeat,
1077 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1078 }
1079 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1080 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1081 self.logical_device_id, device.serial_number,
1082 grouped=True, freq_override=False, **kwargs)
1083 pm_config = self._pm_metrics.make_proto()
1084 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1085 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1086 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1087
1088 # Note, ONU ID and UNI intf set in add_uni_port method
1089 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1090 ani_ports=[self._pon])
1091
1092 # Code to Run OMCI Test Action
1093 kwargs_omci_test_action = {
1094 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1095 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1096 }
1097 serial_number = device.serial_number
1098 self._test_request = OmciTestRequest(self.core_proxy,
1099 self.omci_agent, self.device_id,
1100 AniG, serial_number,
1101 self.logical_device_id,
1102 exclusive=False,
1103 **kwargs_omci_test_action)
1104
1105 self.enabled = True
1106 else:
1107 self.logger.info('onu-already-activated')
1108 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001109
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001111}
1112
1113// doStateConnected get the device info and update to voltha core
1114// for comparison of the original method (not that easy to uncomment): compare here:
1115// voltha-openolt-adapter/adaptercore/device_handler.go
1116// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001117func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001118
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301120 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001123}
1124
1125// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001127
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301129 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132
1133 /*
1134 // Synchronous call to update device state - this method is run in its own go routine
1135 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1136 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001137 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 +00001138 return err
1139 }
1140 return nil
1141 */
1142}
1143
1144// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001148 var err error
1149
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001150 device := dh.device
1151 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001152 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001154 e.Cancel(err)
1155 return
1156 }
1157
1158 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001160 /*
1161 // Update the all ports state on that device to disable
1162 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001163 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001164 return er
1165 }
1166
1167 //Update the device oper state and connection status
1168 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1169 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1170 dh.device = cloned
1171
1172 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001173 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001174 return er
1175 }
1176
1177 //get the child device for the parent device
1178 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1179 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001180 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001181 return err
1182 }
1183 for _, onuDevice := range onuDevices.Items {
1184
1185 // Update onu state as down in onu adapter
1186 onuInd := oop.OnuIndication{}
1187 onuInd.OperState = "down"
1188 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1189 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1190 if er != nil {
1191 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001192 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001193 //Do not return here and continue to process other ONUs
1194 }
1195 }
1196 // * Discovered ONUs entries need to be cleared , since after OLT
1197 // is up, it starts sending discovery indications again* /
1198 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001199 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001200 return nil
1201 */
Himani Chawla4d908332020-08-31 12:30:20 +05301202 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001204 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001205}
1206
Himani Chawla6d2ae152020-09-02 13:11:20 +05301207// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001208// #################################################################################
1209
1210// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301211// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001212
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001213//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001214func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001215 dh.lockDevice.RLock()
1216 pOnuDeviceEntry := dh.pOnuOmciDevice
1217 if aWait && pOnuDeviceEntry == nil {
1218 //keep the read sema short to allow for subsequent write
1219 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001221 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1222 // so it might be needed to wait here for that event with some timeout
1223 select {
1224 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001226 return nil
1227 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001229 // if written now, we can return the written value without sema
1230 return dh.pOnuOmciDevice
1231 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001232 }
mpagenko3af1f032020-06-10 08:53:41 +00001233 dh.lockDevice.RUnlock()
1234 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001235}
1236
Himani Chawla6d2ae152020-09-02 13:11:20 +05301237//setOnuDeviceEntry sets the ONU device entry within the handler
1238func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001239 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001240 dh.lockDevice.Lock()
1241 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001242 dh.pOnuOmciDevice = apDeviceEntry
1243 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001244 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001245}
1246
Himani Chawla6d2ae152020-09-02 13:11:20 +05301247//addOnuDeviceEntry creates a new ONU device or returns the existing
1248func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001250
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001252 if deviceEntry == nil {
1253 /* costum_me_map in python code seems always to be None,
1254 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1255 /* also no 'clock' argument - usage open ...*/
1256 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001257 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001258 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001259 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001261 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001262 // fire deviceEntry ready event to spread to possibly waiting processing
1263 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001265 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267 }
1268 // might be updated with some error handling !!!
1269 return nil
1270}
1271
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1273 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001274 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1275
1276 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001277
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001279 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001280 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001281 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1282 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001283 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284 if err := dh.storePersistentData(ctx); err != nil {
1285 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001286 log.Fields{"device-id": dh.deviceID, "err": err})
1287 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001288 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001289 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001290 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001291 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1292 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001293 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001294 }
1295 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001296 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001297 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001298
1299 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001300 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 +00001301 log.Fields{"device-id": dh.deviceID})
1302 dh.reconciling = false
1303 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001304 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001305 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1306 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1307 // 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 +00001308 // 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 +00001309 // so let's just try to keep it simple ...
1310 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001311 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001312 if err != nil || device == nil {
1313 //TODO: needs to handle error scenarios
1314 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1315 return errors.New("Voltha Device not found")
1316 }
1317 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001318
dbainbri4d3a0dc2020-12-02 00:33:42 +00001319 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001320 return err
mpagenko3af1f032020-06-10 08:53:41 +00001321 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001322
dbainbri4d3a0dc2020-12-02 00:33:42 +00001323 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001324
1325 /* this might be a good time for Omci Verify message? */
1326 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001327 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001328 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001329 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001330 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001331
1332 /* give the handler some time here to wait for the OMCi verification result
1333 after Timeout start and try MibUpload FSM anyway
1334 (to prevent stopping on just not supported OMCI verification from ONU) */
1335 select {
1336 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001337 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001338 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001339 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001340 }
1341
1342 /* In py code it looks earlier (on activate ..)
1343 # Code to Run OMCI Test Action
1344 kwargs_omci_test_action = {
1345 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1346 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1347 }
1348 serial_number = device.serial_number
1349 self._test_request = OmciTestRequest(self.core_proxy,
1350 self.omci_agent, self.device_id,
1351 AniG, serial_number,
1352 self.logical_device_id,
1353 exclusive=False,
1354 **kwargs_omci_test_action)
1355 ...
1356 # Start test requests after a brief pause
1357 if not self._test_request_started:
1358 self._test_request_started = True
1359 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1360 reactor.callLater(tststart, self._test_request.start_collector)
1361
1362 */
1363 /* which is then: in omci_test_request.py : */
1364 /*
1365 def start_collector(self, callback=None):
1366 """
1367 Start the collection loop for an adapter if the frequency > 0
1368
1369 :param callback: (callable) Function to call to collect PM data
1370 """
1371 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1372 if callback is None:
1373 callback = self.perform_test_omci
1374
1375 if self.lc is None:
1376 self.lc = LoopingCall(callback)
1377
1378 if self.default_freq > 0:
1379 self.lc.start(interval=self.default_freq / 10)
1380
1381 def perform_test_omci(self):
1382 """
1383 Perform the initial test request
1384 """
1385 ani_g_entities = self._device.configuration.ani_g_entities
1386 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1387 is not None else None
1388 self._entity_id = ani_g_entities_ids[0]
1389 self.logger.info('perform-test', entity_class=self._entity_class,
1390 entity_id=self._entity_id)
1391 try:
1392 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1393 result = yield self._device.omci_cc.send(frame)
1394 if not result.fields['omci_message'].fields['success_code']:
1395 self.logger.info('Self-Test Submitted Successfully',
1396 code=result.fields[
1397 'omci_message'].fields['success_code'])
1398 else:
1399 raise TestFailure('Test Failure: {}'.format(
1400 result.fields['omci_message'].fields['success_code']))
1401 except TimeoutError as e:
1402 self.deferred.errback(failure.Failure(e))
1403
1404 except Exception as e:
1405 self.logger.exception('perform-test-Error', e=e,
1406 class_id=self._entity_class,
1407 entity_id=self._entity_id)
1408 self.deferred.errback(failure.Failure(e))
1409
1410 */
1411
1412 // PM related heartbeat??? !!!TODO....
1413 //self._heartbeat.enabled = True
1414
mpagenko1cc3cb42020-07-27 15:24:38 +00001415 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1416 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1417 * 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 +05301418 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001419 */
1420 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001421 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001422 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001423 if pMibUlFsm.Is(ulStDisabled) {
1424 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 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 +00001426 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301427 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301429 //Determine ONU status and start/re-start MIB Synchronization tasks
1430 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001431 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301432 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 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 +00001434 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001435 }
Himani Chawla4d908332020-08-31 12:30:20 +05301436 } else {
1437 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 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 +00001439 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301440 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001441 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001442 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001443 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001445 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001446 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001447 }
1448 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001449 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001450 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001451 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001452
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001453 if !dh.getCollectorIsRunning() {
1454 // Start PM collector routine
1455 go dh.startCollector(ctx)
1456 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001457 return nil
1458}
1459
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001461 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001462 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001463 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001464 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001465
mpagenko900ee4b2020-10-12 11:56:34 +00001466 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1467 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1468 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001469 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001470 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001471 log.Fields{"device-id": dh.deviceID, "error": err})
1472 // abort: system behavior is just unstable ...
1473 return err
1474 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001475 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001476 _ = 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 +00001477
1478 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1479 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1480 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001482 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001484 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001485 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001486 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001487
1488 //TODO!!! remove existing traffic profiles
1489 /* from py code, if TP's exist, remove them - not yet implemented
1490 self._tp = dict()
1491 # Let TP download happen again
1492 for uni_id in self._tp_service_specific_task:
1493 self._tp_service_specific_task[uni_id].clear()
1494 for uni_id in self._tech_profile_download_done:
1495 self._tech_profile_download_done[uni_id].clear()
1496 */
1497
dbainbri4d3a0dc2020-12-02 00:33:42 +00001498 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001499
mpagenkofc4f56e2020-11-04 17:17:49 +00001500 dh.ReadyForSpecificOmciConfig = false
1501
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001503 // abort: system behavior is just unstable ...
1504 return err
1505 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001506 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001507 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001509 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001510 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001511 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001512 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001513 // abort: system behavior is just unstable ...
1514 return err
1515 }
1516 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001517 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001518 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001519 return nil
1520}
1521
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001522func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001523 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1524 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1525 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1526 // and using the stop/reset event should never harm
1527
dbainbri4d3a0dc2020-12-02 00:33:42 +00001528 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001529 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001531 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1532 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001533 if includingMibSyncFsm {
1534 //the MibSync FSM might be active all the ONU-active time,
1535 // hence it must be stopped unconditionally
1536 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1537 if pMibUlFsm != nil {
1538 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1539 }
mpagenko900ee4b2020-10-12 11:56:34 +00001540 }
1541 //MibDownload may run
1542 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1543 if pMibDlFsm != nil {
1544 _ = pMibDlFsm.Event(dlEvReset)
1545 }
1546 //port lock/unlock FSM's may be active
1547 if dh.pUnlockStateFsm != nil {
1548 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1549 }
1550 if dh.pLockStateFsm != nil {
1551 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1552 }
1553 //techProfile related PonAniConfigFsm FSM may be active
1554 if dh.pOnuTP != nil {
1555 // should always be the case here
1556 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1557 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001558 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1559 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1560 }
mpagenko900ee4b2020-10-12 11:56:34 +00001561 }
1562 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001563 // reset the possibly existing VlanConfigFsm
1564 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1565 //VlanFilterFsm exists and was already started
1566 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1567 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001568 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001569 // no need to remove specific data
1570 pVlanFilterFsm.RequestClearPersistency(false)
1571 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001572 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1573 }
1574 }
1575 }
1576 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001577 if dh.getCollectorIsRunning() {
1578 // Stop collector routine
1579 dh.stopCollector <- true
1580 }
mpagenko900ee4b2020-10-12 11:56:34 +00001581 return nil
1582}
1583
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1585 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 +05301586
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1588 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001589 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001591 return
1592 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001593 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001594 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1595 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1596 for _, mgmtEntityID := range pptpInstKeys {
1597 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1598 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301600 i++
1601 }
1602 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301604 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001605 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1606 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301607 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001608 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301609 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301611 i++
1612 }
1613 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301615 }
1616 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301618 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001619 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1620 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1621 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1622 * disable/enable toggling here to allow traffic
1623 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1624 * like the py comment says:
1625 * # start by locking all the unis till mib sync and initial mib is downloaded
1626 * # this way we can capture the port down/up events when we are ready
1627 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301628
mpagenkoa40e99a2020-11-17 13:50:39 +00001629 // Init Uni Ports to Admin locked state
1630 // *** should generate UniLockStateDone event *****
1631 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001632 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001633 } else { //LockStateFSM already init
1634 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001636 }
1637}
1638
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1640 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301641 /* Mib download procedure -
1642 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1643 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001645 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001647 return
1648 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301649 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1650 if pMibDlFsm != nil {
1651 if pMibDlFsm.Is(dlStDisabled) {
1652 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 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 +05301654 // maybe try a FSM reset and then again ... - TODO!!!
1655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301657 // maybe use more specific states here for the specific download steps ...
1658 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301660 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301662 //Begin MIB data download (running autonomously)
1663 }
1664 }
1665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001667 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301668 // maybe try a FSM reset and then again ... - TODO!!!
1669 }
1670 /***** Mib download started */
1671 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301673 }
1674}
1675
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1677 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301678 //initiate DevStateUpdate
1679 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001681 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301683 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1684 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301686 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301688 }
1689 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001691 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001693 return
1694 }
1695 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 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 +00001697 log.Fields{"device-id": dh.deviceID})
1698 dh.reconciling = false
1699 return
1700 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301702 log.Fields{"device-id": dh.deviceID})
1703 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
Girish Gowdrae0140f02021-02-02 16:55:09 -08001705
1706 // Initialize classical L2 PM Interval Counters
1707 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1708 // There is no way we should be landing here, but if we do then
1709 // there is nothing much we can do about this other than log error
1710 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1711 }
1712
mpagenkofc4f56e2020-11-04 17:17:49 +00001713 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301714 // *** should generate UniUnlockStateDone event *****
1715 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301717 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301718 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301720 }
1721}
1722
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1724 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301725
1726 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301728 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1730 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001731 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001733 return
1734 }
1735 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 if err := dh.storePersistentData(ctx); err != nil {
1737 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001738 log.Fields{"device-id": dh.deviceID, "err": err})
1739 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301740 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 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 +05301742 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001744 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301745 }
1746}
1747
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1749 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001750 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001752 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1753 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001755 }
1756
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001758 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001760
1761 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001763
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001765 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001767 return
1768 }
1769 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 if err := dh.storePersistentData(ctx); err != nil {
1771 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001772 log.Fields{"device-id": dh.deviceID, "err": err})
1773 }
mpagenko900ee4b2020-10-12 11:56:34 +00001774}
1775
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1777 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001778 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001780 voltha.OperStatus_ACTIVE); err != nil {
1781 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001783 }
1784
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001786 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001787 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001789
1790 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001792
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001794 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001796 return
1797 }
1798 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 if err := dh.storePersistentData(ctx); err != nil {
1800 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001801 log.Fields{"device-id": dh.deviceID, "err": err})
1802 }
mpagenko900ee4b2020-10-12 11:56:34 +00001803}
1804
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001806 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001808 // attention: the device reason update is done based on ONU-UNI-Port related activity
1809 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001810 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001811 // 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 +00001812 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301813 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001814 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001816 }
1817 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001819 // attention: the device reason update is done based on ONU-UNI-Port related activity
1820 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001821 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001822 // 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 +00001823 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001824 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001825 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301826}
1827
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1829 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001830 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301831 // attention: the device reason update is done based on ONU-UNI-Port related activity
1832 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301833
mpagenkofc4f56e2020-11-04 17:17:49 +00001834 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001835 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001836 // which may be the case from some previous actvity on another UNI Port of the ONU
1837 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001838 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001839 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001841 }
1842 }
1843 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001844 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001845 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001847 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301848 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001849 if err := dh.storePersistentData(ctx); err != nil {
1850 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1851 log.Fields{"device-id": dh.deviceID, "err": err})
1852 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301853}
1854
Himani Chawla6d2ae152020-09-02 13:11:20 +05301855//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301857 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001858 case MibDatabaseSync:
1859 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001861 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001862 case UniLockStateDone:
1863 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001865 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001866 case MibDownloadDone:
1867 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001869 }
1870 case UniUnlockStateDone:
1871 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001873 }
mpagenko900ee4b2020-10-12 11:56:34 +00001874 case UniEnableStateDone:
1875 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001877 }
1878 case UniDisableStateDone:
1879 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001881 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001882 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001883 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001885 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001886 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001887 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001889 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001890 default:
1891 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001893 }
1894 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001895}
1896
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001898 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301900 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001901 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001903 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301904 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001906 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001908 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001909 //store UniPort with the System-PortNumber key
1910 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001911 if !dh.reconciling {
1912 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001913 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1914 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001915 } //error logging already within UniPort method
1916 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001917 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001918 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001919 }
1920 }
1921}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001922
mpagenko3af1f032020-06-10 08:53:41 +00001923// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001925 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301926 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001927 // with following remark:
1928 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1929 // # load on the core
1930
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001931 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001932
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001933 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001934 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301935 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301937 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001938 if !dh.reconciling {
1939 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 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 +00001941 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001942 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001944 }
mpagenko3af1f032020-06-10 08:53:41 +00001945 }
1946 }
1947}
1948
1949// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001951 // compare enableUniPortStateUpdate() above
1952 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1953 for uniNo, uniPort := range dh.uniEntityMap {
1954 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301955 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301957 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001958 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 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 +00001960 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001961 }
1962}
1963
1964// ONU_Active/Inactive announcement on system KAFKA bus
1965// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001967 var de voltha.DeviceEvent
1968 eventContext := make(map[string]string)
1969 //Populating event context
1970 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001972 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301974 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001975 }
1976 oltSerialNumber := parentDevice.SerialNumber
1977
1978 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1979 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1980 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05301981 eventContext["olt-serial-number"] = oltSerialNumber
1982 eventContext["device-id"] = aDeviceID
1983 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001985 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001986
1987 /* Populating device event body */
1988 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301989 de.ResourceId = aDeviceID
1990 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001991 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1992 de.Description = fmt.Sprintf("%s Event - %s - %s",
1993 cEventObjectType, cOnuActivatedEvent, "Raised")
1994 } else {
1995 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1996 de.Description = fmt.Sprintf("%s Event - %s - %s",
1997 cEventObjectType, cOnuActivatedEvent, "Cleared")
1998 }
1999 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2001 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302002 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002003 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302005 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002006}
2007
Himani Chawla4d908332020-08-31 12:30:20 +05302008// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002010 chLSFsm := make(chan Message, 2048)
2011 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302012 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002014 sFsmName = "LockStateFSM"
2015 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002017 sFsmName = "UnLockStateFSM"
2018 }
mpagenko3af1f032020-06-10 08:53:41 +00002019
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002021 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002023 return
2024 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002026 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002027 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302028 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002029 dh.pLockStateFsm = pLSFsm
2030 } else {
2031 dh.pUnlockStateFsm = pLSFsm
2032 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002034 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002036 }
2037}
2038
2039// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002040func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002041 /* Uni Port lock/unlock procedure -
2042 ***** should run via 'adminDone' state and generate the argument requested event *****
2043 */
2044 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302045 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002046 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2047 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2048 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002049 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302050 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002051 }
2052 } else {
2053 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2054 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2055 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002056 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302057 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002058 }
2059 }
2060 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002061 if pLSStatemachine.Is(uniStDisabled) {
2062 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002064 // maybe try a FSM reset and then again ... - TODO!!!
2065 } else {
2066 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002068 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002069 }
2070 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002072 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002073 // maybe try a FSM reset and then again ... - TODO!!!
2074 }
2075 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002076 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002077 // maybe try a FSM reset and then again ... - TODO!!!
2078 }
2079}
2080
Himani Chawla6d2ae152020-09-02 13:11:20 +05302081//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002083
2084 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002085 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002086 kvbackend := &db.Backend{
2087 Client: dh.pOpenOnuAc.kvClient,
2088 StoreType: dh.pOpenOnuAc.KVStoreType,
2089 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002090 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002091 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2092 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002093
mpagenkoaf801632020-07-03 10:00:42 +00002094 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002095}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302097 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002098
mpagenkodff5dda2020-08-28 11:52:01 +00002099 for _, field := range flow.GetOfbFields(apFlowItem) {
2100 switch field.Type {
2101 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2102 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002104 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2105 }
mpagenko01e726e2020-10-23 09:45:29 +00002106 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002107 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2108 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302109 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002110 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302111 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2112 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002113 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2114 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002115 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2116 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302117 return
mpagenkodff5dda2020-08-28 11:52:01 +00002118 }
2119 }
mpagenko01e726e2020-10-23 09:45:29 +00002120 */
mpagenkodff5dda2020-08-28 11:52:01 +00002121 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2122 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302123 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002124 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002126 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302127 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002128 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302130 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002131 }
2132 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2133 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302134 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002136 "PCP": loAddPcp})
2137 }
2138 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2139 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002141 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2142 }
2143 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2144 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002146 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2147 }
2148 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2149 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002151 "IPv4-DST": field.GetIpv4Dst()})
2152 }
2153 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2154 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002155 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002156 "IPv4-SRC": field.GetIpv4Src()})
2157 }
2158 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2159 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002161 "Metadata": field.GetTableMetadata()})
2162 }
2163 /*
2164 default:
2165 {
2166 //all other entires ignored
2167 }
2168 */
2169 }
2170 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302171}
mpagenkodff5dda2020-08-28 11:52:01 +00002172
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002174 for _, action := range flow.GetActions(apFlowItem) {
2175 switch action.Type {
2176 /* not used:
2177 case of.OfpActionType_OFPAT_OUTPUT:
2178 {
mpagenko01e726e2020-10-23 09:45:29 +00002179 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002180 "Output": action.GetOutput()})
2181 }
2182 */
2183 case of.OfpActionType_OFPAT_PUSH_VLAN:
2184 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002186 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2187 }
2188 case of.OfpActionType_OFPAT_SET_FIELD:
2189 {
2190 pActionSetField := action.GetSetField()
2191 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002193 "OxcmClass": pActionSetField.Field.OxmClass})
2194 }
2195 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302196 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302198 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002199 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302200 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002201 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302202 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002203 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002205 "Type": pActionSetField.Field.GetOfbField().Type})
2206 }
2207 }
2208 /*
2209 default:
2210 {
2211 //all other entires ignored
2212 }
2213 */
2214 }
2215 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302216}
2217
2218//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302220 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2221 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2222 var loAddPcp, loSetPcp uint8
2223 var loIPProto uint32
2224 /* the TechProfileId is part of the flow Metadata - compare also comment within
2225 * OLT-Adapter:openolt_flowmgr.go
2226 * Metadata 8 bytes:
2227 * Most Significant 2 Bytes = Inner VLAN
2228 * Next 2 Bytes = Tech Profile ID(TPID)
2229 * Least Significant 4 Bytes = Port ID
2230 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2231 * subscriber related flows.
2232 */
2233
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302235 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302237 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002238 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302239 }
mpagenko551a4d42020-12-08 18:09:20 +00002240 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002241 loCookie := apFlowItem.GetCookie()
2242 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002243 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002244 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302245
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002247 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302248 if loIPProto == 2 {
2249 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2250 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002251 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2252 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302253 return nil
2254 }
mpagenko01e726e2020-10-23 09:45:29 +00002255 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002257
2258 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002260 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2261 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2262 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2263 //TODO!!: Use DeviceId within the error response to rwCore
2264 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002265 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002266 }
2267 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002269 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2270 } else {
2271 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2272 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2273 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302274 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002275 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002277 }
mpagenko9a304ea2020-12-16 15:54:01 +00002278
2279 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2280 dh.lockVlanConfig.Lock()
2281 defer dh.lockVlanConfig.Unlock()
2282 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302283 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002285 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002286 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002288 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002289}
2290
2291//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002293 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2294 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2295 //no extra check is done on the rule parameters
2296 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2297 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2298 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2299 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002300 // - 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 +00002301 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002303
2304 /* TT related temporary workaround - should not be needed anymore
2305 for _, field := range flow.GetOfbFields(apFlowItem) {
2306 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2307 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002308 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002309 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2310 if loIPProto == 2 {
2311 // 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 +00002312 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002313 log.Fields{"device-id": dh.deviceID})
2314 return nil
2315 }
2316 }
2317 } //for all OfbFields
2318 */
2319
mpagenko9a304ea2020-12-16 15:54:01 +00002320 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2321 dh.lockVlanConfig.Lock()
2322 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002323 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002325 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002327 log.Fields{"device-id": dh.deviceID})
2328 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002329 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002330 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002331
mpagenko01e726e2020-10-23 09:45:29 +00002332 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002333}
2334
Himani Chawla26e555c2020-08-31 12:30:20 +05302335// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002336// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002337func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002338 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002339 chVlanFilterFsm := make(chan Message, 2048)
2340
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002342 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302344 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002345 }
2346
dbainbri4d3a0dc2020-12-02 00:33:42 +00002347 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002348 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2349 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002350 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302351 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002352 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2353 if pVlanFilterStatemachine != nil {
2354 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2355 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302357 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002358 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302359 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002360 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302361 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2362 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002363 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002365 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302366 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002367 }
2368 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002369 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002370 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302371 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002372 }
2373 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002375 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302376 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002377 }
2378 return nil
2379}
2380
mpagenkofc4f56e2020-11-04 17:17:49 +00002381//VerifyVlanConfigRequest checks on existence of a given uniPort
2382// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002383func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002384 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2385 var pCurrentUniPort *onuUniPort
2386 for _, uniPort := range dh.uniEntityMap {
2387 // only if this port is validated for operState transfer
2388 if uniPort.uniID == uint8(aUniID) {
2389 pCurrentUniPort = uniPort
2390 break //found - end search loop
2391 }
2392 }
2393 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002395 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2396 return
2397 }
mpagenko551a4d42020-12-08 18:09:20 +00002398 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002399}
2400
mpagenkodff5dda2020-08-28 11:52:01 +00002401//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002402func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002403 //TODO!! verify and start pending flow configuration
2404 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2405 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302406 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002407 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2408 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2409 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002410 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2411 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2412 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2413 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2414 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2415 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2416 } else {
2417 /***** UniVlanConfigFsm continued */
2418 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2419 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2420 "UniPort": apUniPort.portNo})
2421 }
2422 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2423 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2424 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2425 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2426 } else {
2427 /***** UniVlanConfigFsm continued */
2428 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2429 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2430 "UniPort": apUniPort.portNo})
2431 }
mpagenkodff5dda2020-08-28 11:52:01 +00002432 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002433 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2434 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002435 "UniPort": apUniPort.portNo})
2436 }
2437 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002438 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2439 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2440 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002441 }
2442 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002443 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002444 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002445 }
mpagenkodff5dda2020-08-28 11:52:01 +00002446 } // else: nothing to do
2447}
2448
2449//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2450// 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 +00002451func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2452 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002453 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2454 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302455 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002456}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002457
Girish Gowdra26a40922021-01-29 17:14:34 -08002458//ProcessPendingTpDelete processes any pending TP delete (if available)
2459func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2460 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2461 if apUniPort == nil {
2462 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2463 return
2464 }
2465 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2466 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2467 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2468 if pAniConfigStatemachine != nil {
2469 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2470 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2471 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2472 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2473 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2474 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2475 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2476 return
2477 }
2478 } else {
2479 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2480 return
2481 }
2482 }
2483 return
2484 }
2485}
2486
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002487//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2488//available for potential reconcilement
2489
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002491
2492 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002494 return nil
2495 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002497
dbainbri4d3a0dc2020-12-02 00:33:42 +00002498 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002499 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002501 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2502 }
2503 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2504
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002505 // deadline context to ensure completion of background routines waited for
2506 //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 +05302507 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002508 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2509
2510 pDevEntry.resetKvProcessingErrorIndication()
2511 var wg sync.WaitGroup
2512 wg.Add(1) // for the 1 go routine to finish
2513
dbainbri4d3a0dc2020-12-02 00:33:42 +00002514 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2515 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002516
2517 return pDevEntry.getKvProcessingErrorIndication()
2518}
2519
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002521 defer cancel() //ensure termination of context (may be pro forma)
2522 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002524 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002525}
2526
dbainbri4d3a0dc2020-12-02 00:33:42 +00002527func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002528
2529 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002530 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002531 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002532 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2533 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002534 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002535 return err
2536 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002537 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002538 return nil
2539 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002541 return nil
2542}
2543
dbainbri4d3a0dc2020-12-02 00:33:42 +00002544func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2545 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002546 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002547 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002548 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2549 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002550 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2551 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2552
2553 pDevEntry.resetKvProcessingErrorIndication()
2554 var wg sync.WaitGroup
2555 wg.Add(1) // for the 1 go routine to finish
2556
2557 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002558 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002559
2560 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002561 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002562 return err
2563 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002564 return nil
2565}
2566
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002567func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2568 var errStr string = ""
2569 for _, err := range errS {
2570 if err != nil {
2571 errStr = errStr + err.Error() + " "
2572 }
2573 }
2574 if errStr != "" {
2575 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2576 }
2577 return nil
2578}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002579
2580// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2581func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2582 dh.lockDevice.RLock()
2583 defer dh.lockDevice.RUnlock()
2584 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2585 return uniPort.entityID, nil
2586 }
2587 return 0, errors.New("error-fetching-uni-port")
2588}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002589
2590// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002591func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2592 var errorsList []error
2593 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 -08002594
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002595 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2596 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2597 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2598
2599 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2600 // successfully.
2601 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2602 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2603 if len(errorsList) > 0 {
2604 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2605 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002606 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002607 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2608 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002609}
2610
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002611func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2612 var err error
2613 var errorsList []error
2614 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2615
2616 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2617 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2618 errorsList = append(errorsList, err)
2619 }
2620 }
2621
2622 return errorsList
2623}
2624
2625func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2626 var err error
2627 var errorsList []error
2628 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2629 // Check if group metric related config is updated
2630 for _, v := range pmConfigs.Groups {
2631 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2632 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2633 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2634
2635 if ok && m.frequency != v.GroupFreq {
2636 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2637 errorsList = append(errorsList, err)
2638 }
2639 }
2640 if ok && m.enabled != v.Enabled {
2641 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2642 errorsList = append(errorsList, err)
2643 }
2644 }
2645 }
2646 return errorsList
2647}
2648
2649func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2650 var err error
2651 var errorsList []error
2652 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2653 // Check if standalone metric related config is updated
2654 for _, v := range pmConfigs.Metrics {
2655 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002656 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002657 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2658
2659 if ok && m.frequency != v.SampleFreq {
2660 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2661 errorsList = append(errorsList, err)
2662 }
2663 }
2664 if ok && m.enabled != v.Enabled {
2665 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2666 errorsList = append(errorsList, err)
2667 }
2668 }
2669 }
2670 return errorsList
2671}
2672
2673// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002674func (dh *deviceHandler) startCollector(ctx context.Context) {
2675 logger.Debugf(ctx, "startingCollector")
2676
2677 // Start routine to process OMCI GET Responses
2678 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002679 // Initialize the next metric collection time.
2680 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2681 // reset like onu rebooted.
2682 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002683 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002684 for {
2685 select {
2686 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002687 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002688 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002689 // Stop the L2 PM FSM
2690 go func() {
2691 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2692 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2693 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2694 }
2695 } else {
2696 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2697 }
2698 }()
2699
Girish Gowdrae09a6202021-01-12 18:10:59 -08002700 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002701 dh.pOnuMetricsMgr.stopTicks <- true
2702
Girish Gowdrae09a6202021-01-12 18:10:59 -08002703 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002704 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2705 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2706 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2707 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2708 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002709 // Update the next metric collection time.
2710 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002711 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002712 } else {
2713 if dh.pmConfigs.Grouped { // metrics are managed as a group
2714 // parse through the group and standalone metrics to see it is time to collect their metrics
2715 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002716
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002717 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2718 // 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 -08002719 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2720 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002721 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2722 }
2723 }
2724 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2725 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2726 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2727 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2728 }
2729 }
2730 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2731
2732 // parse through the group and update the next metric collection time
2733 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2734 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2735 // 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 -08002736 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2737 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002738 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2739 }
2740 }
2741 // parse through the standalone metrics and update the next metric collection time
2742 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2743 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2744 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2745 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2746 }
2747 }
2748 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2749 } /* else { // metrics are not managed as a group
2750 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2751 } */
2752 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002753 }
2754 }
2755}
kesavandfdf77632021-01-26 23:40:33 -05002756
2757func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2758
2759 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2760 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2761}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002762
2763func (dh *deviceHandler) isFsmInState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2764 var currentState string
2765 if pFsm != nil {
2766 currentState = pFsm.Current()
2767 if currentState == wantedState {
2768 return true
2769 }
2770 } else {
2771 logger.Warnw(ctx, "FSM not defined!", log.Fields{"wantedState": wantedState, "device-id": dh.deviceID})
2772 }
2773 return false
2774}
2775
2776func (dh *deviceHandler) mibUploadFsmInIdleState(ctx context.Context, idleState string) bool {
2777 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibUploadFsm.pFsm, idleState)
2778}
2779
2780func (dh *deviceHandler) mibDownloadFsmInIdleState(ctx context.Context, idleState string) bool {
2781 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibDownloadFsm.pFsm, idleState)
2782}
2783
2784func (dh *deviceHandler) devUniLockFsmInIdleState(ctx context.Context, idleState string) bool {
2785 return dh.isFsmInState(ctx, dh.pLockStateFsm.pAdaptFsm.pFsm, idleState)
2786}
2787
2788func (dh *deviceHandler) devUniUnlockFsmInIdleState(ctx context.Context, idleState string) bool {
2789 return dh.isFsmInState(ctx, dh.pUnlockStateFsm.pAdaptFsm.pFsm, idleState)
2790}
2791
2792func (dh *deviceHandler) devAniConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2793 if dh.pOnuTP.pAniConfigFsm != nil {
2794 for _, v := range dh.pOnuTP.pAniConfigFsm {
2795 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2796 return false
2797 }
2798 }
2799 return true
2800 }
2801 logger.Warnw(ctx, "AniConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2802 return false
2803}
2804
2805func (dh *deviceHandler) devUniVlanConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2806 if dh.UniVlanConfigFsmMap != nil {
2807 for _, v := range dh.UniVlanConfigFsmMap {
2808 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2809 return false
2810 }
2811 }
2812 return true
2813 }
2814 logger.Warnw(ctx, "UniVlanConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2815 return false
2816}
2817
Girish Gowdrae0140f02021-02-02 16:55:09 -08002818func (dh *deviceHandler) l2PmFsmInIdleState(ctx context.Context, idleState string) bool {
2819 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2820 return dh.isFsmInState(ctx, dh.pOnuMetricsMgr.pAdaptFsm.pFsm, idleState)
2821 }
2822 logger.Warnw(ctx, "L2 PM FSM not defined!", log.Fields{"device-id": dh.deviceID})
2823 return false
2824}
2825
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002826func (dh *deviceHandler) allButCallingFsmInIdleState(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
2827 for fsmName, fsmStruct := range fsmIdleStateFuncMap {
2828 if fsmName != callingFsm && !fsmStruct.idleCheckFunc(dh, ctx, fsmStruct.idleState) {
2829 return false
2830 }
2831 }
2832 return true
2833}
2834
2835func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
2836 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
2837 if err := dh.resetFsms(ctx, false); err != nil {
2838 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
2839 // TODO: fatal error reset ONU, delete deviceHandler!
2840 return
2841 }
2842 if !dh.getCollectorIsRunning() {
2843 // Start PM collector routine
2844 go dh.startCollector(ctx)
2845 }
2846 dh.uniEntityMap = make(map[uint32]*onuUniPort)
2847 dh.reconciling = true
2848}
2849
2850func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
2851 dh.mutexCollectorFlag.Lock()
2852 dh.collectorIsRunning = flagValue
2853 dh.mutexCollectorFlag.Unlock()
2854}
2855
2856func (dh *deviceHandler) getCollectorIsRunning() bool {
2857 dh.mutexCollectorFlag.RLock()
2858 flagValue := dh.collectorIsRunning
2859 dh.mutexCollectorFlag.RUnlock()
2860 return flagValue
2861}