blob: 5db246b8fe2dcef1937432642bf6d451fddcecc9 [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
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530180 pAlarmMgr *onuAlarmManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000181 exitChannel chan int
182 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000183 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000184 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530185 pLockStateFsm *lockStateFsm
186 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000188 //flowMgr *OpenOltFlowMgr
189 //eventMgr *OpenOltEventMgr
190 //resourceMgr *rsrcMgr.OpenOltResourceMgr
191
192 //discOnus sync.Map
193 //onus sync.Map
194 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000195 collectorIsRunning bool
196 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000197 stopCollector chan bool
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530198 stopAlarmManager chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000199 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000200 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000201 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000202 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
203 reconciling bool
204 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000205}
206
Himani Chawla6d2ae152020-09-02 13:11:20 +0530207//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530208func 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 +0530209 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210 dh.coreProxy = cp
211 dh.AdapterProxy = ap
212 dh.EventProxy = ep
213 cloned := (proto.Clone(device)).(*voltha.Device)
214 dh.deviceID = cloned.Id
215 dh.DeviceType = cloned.Type
216 dh.adminState = "up"
217 dh.device = cloned
218 dh.pOpenOnuAc = adapter
219 dh.exitChannel = make(chan int, 1)
220 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000221 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000222 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000223 dh.stopCollector = make(chan bool, 2)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530224 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225 dh.stopHeartbeatCheck = make(chan bool, 2)
226 //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 +0000227 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530228 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000229 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000230 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000231 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000232 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800234 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
235 dh.pmConfigs = cloned.PmConfigs
236 } /* else {
237 // will be populated when onu_metrics_mananger is initialized.
238 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800239
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 // Device related state machine
241 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000242 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000244 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
245 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
246 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
247 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
248 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 },
250 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000251 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
252 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
253 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
254 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
255 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
256 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
257 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
258 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 },
260 )
mpagenkoaf801632020-07-03 10:00:42 +0000261
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000262 return &dh
263}
264
Himani Chawla6d2ae152020-09-02 13:11:20 +0530265// start save the device to the data model
266func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000267 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270}
271
Himani Chawla4d908332020-08-31 12:30:20 +0530272/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000273// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530274func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000275 logger.Debug("stopping-device-handler")
276 dh.exitChannel <- 1
277}
Himani Chawla4d908332020-08-31 12:30:20 +0530278*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279
280// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530281// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000282
Girish Gowdrae0140f02021-02-02 16:55:09 -0800283//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530284func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000288 if dh.pDeviceStateFsm.Is(devStNull) {
289 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000292 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800293 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
294 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800295 // Now, set the initial PM configuration for that device
296 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
297 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
298 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800299 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 }
303
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304}
305
mpagenko057889c2021-01-21 16:51:58 +0000306func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530307 msgBody := msg.GetBody()
308 omciMsg := &ic.InterAdapterOmciMessage{}
309 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530311 "device-id": dh.deviceID, "error": err})
312 return err
313 }
314
315 //assuming omci message content is hex coded!
316 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000317 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530318 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
319 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530321 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000322 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000323 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000324 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000325 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 +0530326 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000328 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530329}
330
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530333 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000334
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000336
dbainbri4d3a0dc2020-12-02 00:33:42 +0000337 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000338 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000340 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
341 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 if dh.pOnuTP == nil {
343 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000346 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000348 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000350 "device-state": deviceReasonMap[dh.deviceReason]})
351 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000353 //previous state test here was just this one, now extended for more states to reject the SetRequest:
354 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
355 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530356
357 msgBody := msg.GetBody()
358 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
359 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000360 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 "device-id": dh.deviceID, "error": err})
362 return err
363 }
364
365 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
367 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000369 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370
371 if techProfMsg.UniId > 255 {
372 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
373 techProfMsg.UniId, dh.deviceID))
374 }
375 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800376 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
377 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800379 return err
380 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000381
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530383 // if there has been some change for some uni TechProfilePath
384 //in order to allow concurrent calls to other dh instances we do not wait for execution here
385 //but doing so we can not indicate problems to the caller (who does what with that then?)
386 //by now we just assume straightforward successful execution
387 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
388 // possible problems to the caller later autonomously
389
390 // deadline context to ensure completion of background routines waited for
391 //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 +0530392 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 dctx, cancel := context.WithDeadline(context.Background(), deadline)
394
Girish Gowdra041dcb32020-11-16 16:54:30 -0800395 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 pDevEntry.resetKvProcessingErrorIndication()
397
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 var wg sync.WaitGroup
399 wg.Add(2) // for the 2 go routines to finish
400 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000401 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
402 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
403 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404
Girish Gowdra041dcb32020-11-16 16:54:30 -0800405 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530406 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000407 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530408 return nil
409}
410
Himani Chawla6d2ae152020-09-02 13:11:20 +0530411func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530413 msg *ic.InterAdapterMessage) error {
414
dbainbri4d3a0dc2020-12-02 00:33:42 +0000415 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000416
dbainbri4d3a0dc2020-12-02 00:33:42 +0000417 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000419 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
421 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 if dh.pOnuTP == nil {
423 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530427 }
428
429 msgBody := msg.GetBody()
430 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
431 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530433 "device-id": dh.deviceID, "error": err})
434 return err
435 }
436
437 //compare TECH_PROFILE_DOWNLOAD_REQUEST
438 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000439 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530440
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441 if delGemPortMsg.UniId > 255 {
442 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
443 delGemPortMsg.UniId, dh.deviceID))
444 }
445 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800446 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
447 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000448 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 -0800449 return err
450 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530451
mpagenkofc4f56e2020-11-04 17:17:49 +0000452 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453
mpagenkofc4f56e2020-11-04 17:17:49 +0000454 // deadline context to ensure completion of background routines waited for
455 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
456 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000457
Girish Gowdra041dcb32020-11-16 16:54:30 -0800458 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459
mpagenkofc4f56e2020-11-04 17:17:49 +0000460 var wg sync.WaitGroup
461 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000462 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000463 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000464 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000465
Girish Gowdra041dcb32020-11-16 16:54:30 -0800466 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530467}
468
Himani Chawla6d2ae152020-09-02 13:11:20 +0530469func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530471 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000472
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000474
dbainbri4d3a0dc2020-12-02 00:33:42 +0000475 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
479 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 if dh.pOnuTP == nil {
481 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 }
486
487 msgBody := msg.GetBody()
488 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
489 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 "device-id": dh.deviceID, "error": err})
492 return err
493 }
494
495 //compare TECH_PROFILE_DOWNLOAD_REQUEST
496 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498
499 if delTcontMsg.UniId > 255 {
500 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
501 delTcontMsg.UniId, dh.deviceID))
502 }
503 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800504 tpPath := delTcontMsg.TpPath
505 tpID, err := GetTpIDFromTpPath(tpPath)
506 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 return err
509 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510
dbainbri4d3a0dc2020-12-02 00:33:42 +0000511 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530512 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530513 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530514 dctx, cancel := context.WithDeadline(context.Background(), deadline)
515
Girish Gowdra041dcb32020-11-16 16:54:30 -0800516 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000517 pDevEntry.resetKvProcessingErrorIndication()
518
Himani Chawla26e555c2020-08-31 12:30:20 +0530519 var wg sync.WaitGroup
520 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530522 cResourceTcont, delTcontMsg.AllocId, &wg)
523 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
525 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526
Girish Gowdra041dcb32020-11-16 16:54:30 -0800527 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530528 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 return nil
530}
531
Himani Chawla6d2ae152020-09-02 13:11:20 +0530532//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000533// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
534// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000535func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000536 msgID := msg.Header.Id
537 msgType := msg.Header.Type
538 fromTopic := msg.Header.FromTopic
539 toTopic := msg.Header.ToTopic
540 toDeviceID := msg.Header.ToDeviceId
541 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000542 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000543 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
544
545 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000546 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000547 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
548 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000549 {
mpagenko057889c2021-01-21 16:51:58 +0000550 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000551 }
mpagenkoaf801632020-07-03 10:00:42 +0000552 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
553 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000554 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000555 }
556 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
557 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000558 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000559
mpagenkoaf801632020-07-03 10:00:42 +0000560 }
561 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
562 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000564 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000565 default:
566 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000567 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000568 "msgType": msg.Header.Type, "device-id": dh.deviceID})
569 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000570 }
571 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000572}
573
mpagenkodff5dda2020-08-28 11:52:01 +0000574//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
576 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000577 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000578 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000579
mpagenko01e726e2020-10-23 09:45:29 +0000580 var retError error = nil
581 //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 +0000582 if apOfFlowChanges.ToRemove != nil {
583 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000584 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000585 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000586 "device-id": dh.deviceID})
587 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000588 continue
589 }
590 flowInPort := flow.GetInPort(flowItem)
591 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000592 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 +0000593 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
594 continue
595 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000596 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000597 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000598 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000599 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000600 continue
601 } else {
602 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530603 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000604 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
605 loUniPort = uniPort
606 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000608 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
609 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
610 flowInPort, dh.deviceID)
611 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000612 }
613 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000615 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000616 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000618 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000619 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000621 log.Fields{"device-id": dh.deviceID, "error": err})
622 retError = err
623 continue
624 //return err
625 } else { // if last setting succeeds, overwrite possibly previously set error
626 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000627 }
628 }
629 }
630 }
mpagenko01e726e2020-10-23 09:45:29 +0000631 if apOfFlowChanges.ToAdd != nil {
632 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
633 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000635 "device-id": dh.deviceID})
636 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
637 continue
638 }
639 flowInPort := flow.GetInPort(flowItem)
640 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 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 +0000642 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
643 continue
644 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
645 } else if flowInPort == dh.ponPortNumber {
646 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000648 "device-id": dh.deviceID, "inPort": flowInPort})
649 continue
650 } else {
651 // this is the relevant upstream flow
652 var loUniPort *onuUniPort
653 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
654 loUniPort = uniPort
655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000657 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
658 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
659 flowInPort, dh.deviceID)
660 continue
661 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
662 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000663 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
664 // if not, we just throw some error here to have an indication about that, if we really need to support that
665 // then we would need to create some means to activate the internal stored flows
666 // after the device gets active automatically (and still with its dependency to the TechProfile)
667 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
668 // also abort for the other still possible flows here
669 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000671 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 return fmt.Errorf("improper device state on device %s", dh.deviceID)
673 }
674
mpagenko01e726e2020-10-23 09:45:29 +0000675 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000677 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
678 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000680 //try next flow after processing error
681 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000683 log.Fields{"device-id": dh.deviceID, "error": err})
684 retError = err
685 continue
686 //return err
687 } else { // if last setting succeeds, overwrite possibly previously set error
688 retError = nil
689 }
690 }
691 }
692 }
693 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000694}
695
Himani Chawla6d2ae152020-09-02 13:11:20 +0530696//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000697//following are the expected device states after this activity:
698//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
699// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
701 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000702
mpagenko900ee4b2020-10-12 11:56:34 +0000703 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000704 //note that disableDevice sequences in some 'ONU active' state may yield also
705 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000706 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000707 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000708 //disable-device shall be just a UNi/ONU-G related admin state setting
709 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000710
mpagenkofc4f56e2020-11-04 17:17:49 +0000711 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000712 // disable UNI ports/ONU
713 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
714 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000716 } else { //LockStateFSM already init
717 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000719 }
720 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000722 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000724 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
725 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000727 }
mpagenko01e726e2020-10-23 09:45:29 +0000728 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000729
730 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000732 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300733 }
734}
735
Himani Chawla6d2ae152020-09-02 13:11:20 +0530736//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
738 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000739
mpagenkofc4f56e2020-11-04 17:17:49 +0000740 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
741 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
742 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
743 // for real ONU's that should have nearly no influence
744 // Note that for real ONU's there is anyway a problematic situation with following sequence:
745 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
746 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
747 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
748 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
749
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000750 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000751 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000752 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000754 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000755 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000757 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300758}
759
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
761 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000762
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000764 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000766 return
767 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000769 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000771 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000773 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000774 dh.reconciling = false
775 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000776 }
Himani Chawla4d908332020-08-31 12:30:20 +0530777 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000778 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
779 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
780 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
781 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000783}
784
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
786 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000787
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000789 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000791 return
792 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000793 dh.pOnuTP.lockTpProcMutex()
794 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000795 pDevEntry.persUniConfigMutex.RLock()
796 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000797
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000798 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000800 log.Fields{"device-id": dh.deviceID})
801 dh.reconciling = false
802 return
803 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000804 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000805 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
806 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000808 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
809 dh.reconciling = false
810 return
811 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800812 for tpID := range uniData.PersTpPathMap {
813 // deadline context to ensure completion of background routines waited for
814 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
815 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000817
Girish Gowdra041dcb32020-11-16 16:54:30 -0800818 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
819 var wg sync.WaitGroup
820 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
822 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800823 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800825 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000827 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000828 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000829 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
830 dh.reconciling = false
831 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 }
833}
834
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
836 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000837
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000839 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000841 return
842 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000843 pDevEntry.persUniConfigMutex.RLock()
844 defer pDevEntry.persUniConfigMutex.RUnlock()
845
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000846 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000848 log.Fields{"device-id": dh.deviceID})
849 dh.reconciling = false
850 return
851 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000853 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
854 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000856 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
857 dh.reconciling = false
858 return
859 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 var uniPort *onuUniPort
861 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000865 return
866 }
867 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000869 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000872 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
873 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000878 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000879 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000881 }
882 }
883 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000884 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000886 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
887 dh.reconciling = false
888 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000889 }
890}
891
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
893 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 +0000894
895 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000896 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000897}
898
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
900 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000901
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000904 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000906 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000907 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000908
909 // deadline context to ensure completion of background routines waited for
910 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +0530911 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000912 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000913
914 pDevEntry.resetKvProcessingErrorIndication()
915
916 var wg sync.WaitGroup
917 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
919 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000920
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000923}
924
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
926 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300927 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000929 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300930 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000931 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530932 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000933 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530934 return err
935 }
mpagenko01e726e2020-10-23 09:45:29 +0000936
937 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000939
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000941 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300943 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000944 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300946 return err
947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300949 return err
950 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000951 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000952 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
953 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
954 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
955 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300956 return nil
957}
958
mpagenkoc8bba412021-01-15 15:38:44 +0000959//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
960func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
961 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
962 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000963 //return success to comfort the core processing during integration
964 return nil
965 // TODO!!: also verify error response behavior
966 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000967}
968
Himani Chawla6d2ae152020-09-02 13:11:20 +0530969// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000970// #####################################################################################
971
972// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530973// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000974
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
976 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000977}
978
979// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981
dbainbri4d3a0dc2020-12-02 00:33:42 +0000982 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000983 var err error
984
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000985 // populate what we know. rest comes later after mib sync
986 dh.device.Root = false
987 dh.device.Vendor = "OpenONU"
988 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000989 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000990 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000991
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000992 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000993
994 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
996 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530997 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000998 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001000 log.Fields{"device-id": dh.deviceID})
1001 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001002
Himani Chawla4d908332020-08-31 12:30:20 +05301003 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001004 dh.ponPortNumber = dh.device.ParentPortNo
1005
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001006 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1007 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1008 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001010 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301011 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001012
1013 /*
1014 self._pon = PonPort.create(self, self._pon_port_number)
1015 self._pon.add_peer(self.parent_id, self._pon_port_number)
1016 self.logger.debug('adding-pon-port-to-agent',
1017 type=self._pon.get_port().type,
1018 admin_state=self._pon.get_port().admin_state,
1019 oper_status=self._pon.get_port().oper_status,
1020 )
1021 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001022 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001024 var ponPortNo uint32 = 1
1025 if dh.ponPortNumber != 0 {
1026 ponPortNo = dh.ponPortNumber
1027 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001028
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001029 pPonPort := &voltha.Port{
1030 PortNo: ponPortNo,
1031 Label: fmt.Sprintf("pon-%d", ponPortNo),
1032 Type: voltha.Port_PON_ONU,
1033 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301034 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001035 PortNo: ponPortNo}}, // Peer port is parent's port number
1036 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001037 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1038 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001039 e.Cancel(err)
1040 return
1041 }
1042 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001044 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001045 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001046}
1047
1048// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001052 var err error
1053 /*
1054 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1055 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1056 return nil
1057 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1059 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001060 e.Cancel(err)
1061 return
1062 }
1063
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001064 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001066 // reconcilement will be continued after mib download is done
1067 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001068
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069 /*
1070 ############################################################################
1071 # Setup Alarm handler
1072 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1073 device.serial_number)
1074 ############################################################################
1075 # Setup PM configuration for this device
1076 # Pass in ONU specific options
1077 kwargs = {
1078 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1079 'heartbeat': self.heartbeat,
1080 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1081 }
1082 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1083 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1084 self.logical_device_id, device.serial_number,
1085 grouped=True, freq_override=False, **kwargs)
1086 pm_config = self._pm_metrics.make_proto()
1087 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1088 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1089 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1090
1091 # Note, ONU ID and UNI intf set in add_uni_port method
1092 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1093 ani_ports=[self._pon])
1094
1095 # Code to Run OMCI Test Action
1096 kwargs_omci_test_action = {
1097 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1098 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1099 }
1100 serial_number = device.serial_number
1101 self._test_request = OmciTestRequest(self.core_proxy,
1102 self.omci_agent, self.device_id,
1103 AniG, serial_number,
1104 self.logical_device_id,
1105 exclusive=False,
1106 **kwargs_omci_test_action)
1107
1108 self.enabled = True
1109 else:
1110 self.logger.info('onu-already-activated')
1111 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001112
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114}
1115
1116// doStateConnected get the device info and update to voltha core
1117// for comparison of the original method (not that easy to uncomment): compare here:
1118// voltha-openolt-adapter/adaptercore/device_handler.go
1119// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301123 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001126}
1127
1128// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301132 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001134 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135
1136 /*
1137 // Synchronous call to update device state - this method is run in its own go routine
1138 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1139 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001140 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001141 return err
1142 }
1143 return nil
1144 */
1145}
1146
1147// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001149
dbainbri4d3a0dc2020-12-02 00:33:42 +00001150 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001151 var err error
1152
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001153 device := dh.device
1154 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001157 e.Cancel(err)
1158 return
1159 }
1160
1161 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001163 /*
1164 // Update the all ports state on that device to disable
1165 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001166 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001167 return er
1168 }
1169
1170 //Update the device oper state and connection status
1171 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1172 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1173 dh.device = cloned
1174
1175 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001176 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001177 return er
1178 }
1179
1180 //get the child device for the parent device
1181 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1182 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001183 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001184 return err
1185 }
1186 for _, onuDevice := range onuDevices.Items {
1187
1188 // Update onu state as down in onu adapter
1189 onuInd := oop.OnuIndication{}
1190 onuInd.OperState = "down"
1191 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1192 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1193 if er != nil {
1194 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001195 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001196 //Do not return here and continue to process other ONUs
1197 }
1198 }
1199 // * Discovered ONUs entries need to be cleared , since after OLT
1200 // is up, it starts sending discovery indications again* /
1201 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001202 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203 return nil
1204 */
Himani Chawla4d908332020-08-31 12:30:20 +05301205 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001207 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001208}
1209
Himani Chawla6d2ae152020-09-02 13:11:20 +05301210// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001211// #################################################################################
1212
1213// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301214// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001215
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001216//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001218 dh.lockDevice.RLock()
1219 pOnuDeviceEntry := dh.pOnuOmciDevice
1220 if aWait && pOnuDeviceEntry == nil {
1221 //keep the read sema short to allow for subsequent write
1222 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001224 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1225 // so it might be needed to wait here for that event with some timeout
1226 select {
1227 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001229 return nil
1230 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001232 // if written now, we can return the written value without sema
1233 return dh.pOnuOmciDevice
1234 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001235 }
mpagenko3af1f032020-06-10 08:53:41 +00001236 dh.lockDevice.RUnlock()
1237 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001238}
1239
Himani Chawla6d2ae152020-09-02 13:11:20 +05301240//setOnuDeviceEntry sets the ONU device entry within the handler
1241func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301242 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001243 dh.lockDevice.Lock()
1244 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001245 dh.pOnuOmciDevice = apDeviceEntry
1246 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001247 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301248 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001249}
1250
Himani Chawla6d2ae152020-09-02 13:11:20 +05301251//addOnuDeviceEntry creates a new ONU device or returns the existing
1252func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001254
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001256 if deviceEntry == nil {
1257 /* costum_me_map in python code seems always to be None,
1258 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1259 /* also no 'clock' argument - usage open ...*/
1260 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001261 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001262 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001263 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301264 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001265 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301266 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001267 // fire deviceEntry ready event to spread to possibly waiting processing
1268 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001270 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001272 }
1273 // might be updated with some error handling !!!
1274 return nil
1275}
1276
dbainbri4d3a0dc2020-12-02 00:33:42 +00001277func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1278 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001279 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1280
1281 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001282
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001284 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001286 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1287 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001288 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001289 if err := dh.storePersistentData(ctx); err != nil {
1290 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001291 log.Fields{"device-id": dh.deviceID, "err": err})
1292 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001293 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001294 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001296 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1297 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001299 }
1300 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001302 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001303
1304 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001305 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 +00001306 log.Fields{"device-id": dh.deviceID})
1307 dh.reconciling = false
1308 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001309 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001310 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1311 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1312 // 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 +00001313 // 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 +00001314 // so let's just try to keep it simple ...
1315 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001316 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001317 if err != nil || device == nil {
1318 //TODO: needs to handle error scenarios
1319 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1320 return errors.New("Voltha Device not found")
1321 }
1322 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001323
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001325 return err
mpagenko3af1f032020-06-10 08:53:41 +00001326 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001327
dbainbri4d3a0dc2020-12-02 00:33:42 +00001328 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329
1330 /* this might be a good time for Omci Verify message? */
1331 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001332 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001333 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001334 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001335 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001336
1337 /* give the handler some time here to wait for the OMCi verification result
1338 after Timeout start and try MibUpload FSM anyway
1339 (to prevent stopping on just not supported OMCI verification from ONU) */
1340 select {
1341 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001342 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001343 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001344 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001345 }
1346
1347 /* In py code it looks earlier (on activate ..)
1348 # Code to Run OMCI Test Action
1349 kwargs_omci_test_action = {
1350 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1351 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1352 }
1353 serial_number = device.serial_number
1354 self._test_request = OmciTestRequest(self.core_proxy,
1355 self.omci_agent, self.device_id,
1356 AniG, serial_number,
1357 self.logical_device_id,
1358 exclusive=False,
1359 **kwargs_omci_test_action)
1360 ...
1361 # Start test requests after a brief pause
1362 if not self._test_request_started:
1363 self._test_request_started = True
1364 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1365 reactor.callLater(tststart, self._test_request.start_collector)
1366
1367 */
1368 /* which is then: in omci_test_request.py : */
1369 /*
1370 def start_collector(self, callback=None):
1371 """
1372 Start the collection loop for an adapter if the frequency > 0
1373
1374 :param callback: (callable) Function to call to collect PM data
1375 """
1376 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1377 if callback is None:
1378 callback = self.perform_test_omci
1379
1380 if self.lc is None:
1381 self.lc = LoopingCall(callback)
1382
1383 if self.default_freq > 0:
1384 self.lc.start(interval=self.default_freq / 10)
1385
1386 def perform_test_omci(self):
1387 """
1388 Perform the initial test request
1389 """
1390 ani_g_entities = self._device.configuration.ani_g_entities
1391 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1392 is not None else None
1393 self._entity_id = ani_g_entities_ids[0]
1394 self.logger.info('perform-test', entity_class=self._entity_class,
1395 entity_id=self._entity_id)
1396 try:
1397 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1398 result = yield self._device.omci_cc.send(frame)
1399 if not result.fields['omci_message'].fields['success_code']:
1400 self.logger.info('Self-Test Submitted Successfully',
1401 code=result.fields[
1402 'omci_message'].fields['success_code'])
1403 else:
1404 raise TestFailure('Test Failure: {}'.format(
1405 result.fields['omci_message'].fields['success_code']))
1406 except TimeoutError as e:
1407 self.deferred.errback(failure.Failure(e))
1408
1409 except Exception as e:
1410 self.logger.exception('perform-test-Error', e=e,
1411 class_id=self._entity_class,
1412 entity_id=self._entity_id)
1413 self.deferred.errback(failure.Failure(e))
1414
1415 */
1416
1417 // PM related heartbeat??? !!!TODO....
1418 //self._heartbeat.enabled = True
1419
mpagenko1cc3cb42020-07-27 15:24:38 +00001420 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1421 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1422 * 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 +05301423 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001424 */
1425 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001426 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001427 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001428 if pMibUlFsm.Is(ulStDisabled) {
1429 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 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 +00001431 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301432 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301434 //Determine ONU status and start/re-start MIB Synchronization tasks
1435 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001436 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301437 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 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 +00001439 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440 }
Himani Chawla4d908332020-08-31 12:30:20 +05301441 } else {
1442 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 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 +00001444 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301445 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001447 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001448 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001449 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001450 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001451 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 }
1453 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001454 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001455 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001456 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001457
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001458 if !dh.getCollectorIsRunning() {
1459 // Start PM collector routine
1460 go dh.startCollector(ctx)
1461 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301462 go dh.startAlarmManager(ctx)
1463
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001464 return nil
1465}
1466
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001468 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001469 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001470 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001472
mpagenko900ee4b2020-10-12 11:56:34 +00001473 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1474 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1475 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001476 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001478 log.Fields{"device-id": dh.deviceID, "error": err})
1479 // abort: system behavior is just unstable ...
1480 return err
1481 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001482 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 _ = 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 +00001484
1485 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1486 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1487 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001488 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001489 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001490 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001491 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001492 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001494
1495 //TODO!!! remove existing traffic profiles
1496 /* from py code, if TP's exist, remove them - not yet implemented
1497 self._tp = dict()
1498 # Let TP download happen again
1499 for uni_id in self._tp_service_specific_task:
1500 self._tp_service_specific_task[uni_id].clear()
1501 for uni_id in self._tech_profile_download_done:
1502 self._tech_profile_download_done[uni_id].clear()
1503 */
1504
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001506
mpagenkofc4f56e2020-11-04 17:17:49 +00001507 dh.ReadyForSpecificOmciConfig = false
1508
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001510 // abort: system behavior is just unstable ...
1511 return err
1512 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001513 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001514 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001516 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001517 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001519 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001520 // abort: system behavior is just unstable ...
1521 return err
1522 }
1523 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001524 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001525 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526 return nil
1527}
1528
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001529func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001530 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1531 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1532 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1533 // and using the stop/reset event should never harm
1534
dbainbri4d3a0dc2020-12-02 00:33:42 +00001535 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001536 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001538 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1539 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001540 if includingMibSyncFsm {
1541 //the MibSync FSM might be active all the ONU-active time,
1542 // hence it must be stopped unconditionally
1543 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1544 if pMibUlFsm != nil {
1545 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1546 }
mpagenko900ee4b2020-10-12 11:56:34 +00001547 }
1548 //MibDownload may run
1549 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1550 if pMibDlFsm != nil {
1551 _ = pMibDlFsm.Event(dlEvReset)
1552 }
1553 //port lock/unlock FSM's may be active
1554 if dh.pUnlockStateFsm != nil {
1555 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1556 }
1557 if dh.pLockStateFsm != nil {
1558 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1559 }
1560 //techProfile related PonAniConfigFsm FSM may be active
1561 if dh.pOnuTP != nil {
1562 // should always be the case here
1563 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1564 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001565 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1566 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1567 }
mpagenko900ee4b2020-10-12 11:56:34 +00001568 }
1569 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001570 // reset the possibly existing VlanConfigFsm
1571 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1572 //VlanFilterFsm exists and was already started
1573 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1574 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001575 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001576 // no need to remove specific data
1577 pVlanFilterFsm.RequestClearPersistency(false)
1578 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001579 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1580 }
1581 }
1582 }
1583 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001584 if dh.getCollectorIsRunning() {
1585 // Stop collector routine
1586 dh.stopCollector <- true
1587 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301588 dh.stopAlarmManager <- true
mpagenko900ee4b2020-10-12 11:56:34 +00001589 return nil
1590}
1591
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1593 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 +05301594
dbainbri4d3a0dc2020-12-02 00:33:42 +00001595 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1596 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001597 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001599 return
1600 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001601 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001602 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1603 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1604 for _, mgmtEntityID := range pptpInstKeys {
1605 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1606 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301608 i++
1609 }
1610 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301612 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001613 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1614 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301615 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001616 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301617 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301619 i++
1620 }
1621 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301623 }
1624 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301626 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001627 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1628 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1629 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1630 * disable/enable toggling here to allow traffic
1631 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1632 * like the py comment says:
1633 * # start by locking all the unis till mib sync and initial mib is downloaded
1634 * # this way we can capture the port down/up events when we are ready
1635 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301636
mpagenkoa40e99a2020-11-17 13:50:39 +00001637 // Init Uni Ports to Admin locked state
1638 // *** should generate UniLockStateDone event *****
1639 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001641 } else { //LockStateFSM already init
1642 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001644 }
1645}
1646
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1648 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301649 /* Mib download procedure -
1650 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1651 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001653 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001655 return
1656 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301657 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1658 if pMibDlFsm != nil {
1659 if pMibDlFsm.Is(dlStDisabled) {
1660 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 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 +05301662 // maybe try a FSM reset and then again ... - TODO!!!
1663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301665 // maybe use more specific states here for the specific download steps ...
1666 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301668 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301670 //Begin MIB data download (running autonomously)
1671 }
1672 }
1673 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001675 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 // maybe try a FSM reset and then again ... - TODO!!!
1677 }
1678 /***** Mib download started */
1679 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301681 }
1682}
1683
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1685 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301686 //initiate DevStateUpdate
1687 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001689 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301691 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1692 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301694 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301696 }
1697 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001699 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001701 return
1702 }
1703 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 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 +00001705 log.Fields{"device-id": dh.deviceID})
1706 dh.reconciling = false
1707 return
1708 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301710 log.Fields{"device-id": dh.deviceID})
1711 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
Girish Gowdrae0140f02021-02-02 16:55:09 -08001713
1714 // Initialize classical L2 PM Interval Counters
1715 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1716 // There is no way we should be landing here, but if we do then
1717 // there is nothing much we can do about this other than log error
1718 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1719 }
1720
mpagenkofc4f56e2020-11-04 17:17:49 +00001721 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301722 // *** should generate UniUnlockStateDone event *****
1723 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301725 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301726 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301728 }
1729}
1730
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1732 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301733
1734 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301736 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1738 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001739 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001740 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001741 return
1742 }
1743 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 if err := dh.storePersistentData(ctx); err != nil {
1745 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001746 log.Fields{"device-id": dh.deviceID, "err": err})
1747 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301748 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 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 +05301750 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001752 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301753 }
1754}
1755
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1757 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001758 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001760 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1761 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001763 }
1764
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001766 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001768
1769 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001771
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001773 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001775 return
1776 }
1777 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 if err := dh.storePersistentData(ctx); err != nil {
1779 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001780 log.Fields{"device-id": dh.deviceID, "err": err})
1781 }
mpagenko900ee4b2020-10-12 11:56:34 +00001782}
1783
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1785 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001786 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001788 voltha.OperStatus_ACTIVE); err != nil {
1789 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001791 }
1792
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001794 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001795 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001797
1798 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001800
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001802 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001804 return
1805 }
1806 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 if err := dh.storePersistentData(ctx); err != nil {
1808 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001809 log.Fields{"device-id": dh.deviceID, "err": err})
1810 }
mpagenko900ee4b2020-10-12 11:56:34 +00001811}
1812
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001814 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001816 // attention: the device reason update is done based on ONU-UNI-Port related activity
1817 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001818 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001819 // 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 +00001820 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301821 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001822 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001824 }
1825 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001827 // attention: the device reason update is done based on ONU-UNI-Port related activity
1828 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001829 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001830 // 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 +00001831 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001832 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001833 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301834}
1835
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1837 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001838 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301839 // attention: the device reason update is done based on ONU-UNI-Port related activity
1840 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301841
mpagenkofc4f56e2020-11-04 17:17:49 +00001842 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001843 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001844 // which may be the case from some previous actvity on another UNI Port of the ONU
1845 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001847 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001849 }
1850 }
1851 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001852 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001853 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001855 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301856 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001857 if err := dh.storePersistentData(ctx); err != nil {
1858 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1859 log.Fields{"device-id": dh.deviceID, "err": err})
1860 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301861}
1862
Himani Chawla6d2ae152020-09-02 13:11:20 +05301863//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301865 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001866 case MibDatabaseSync:
1867 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001869 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001870 case UniLockStateDone:
1871 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001873 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001874 case MibDownloadDone:
1875 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001877 }
1878 case UniUnlockStateDone:
1879 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001881 }
mpagenko900ee4b2020-10-12 11:56:34 +00001882 case UniEnableStateDone:
1883 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001885 }
1886 case UniDisableStateDone:
1887 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001889 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001890 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001891 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001893 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001894 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001895 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001897 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001898 default:
1899 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001901 }
1902 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001903}
1904
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001906 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301908 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001909 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001911 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301912 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001913 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001914 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001915 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001916 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001917 //store UniPort with the System-PortNumber key
1918 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001919 if !dh.reconciling {
1920 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1922 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001923 } //error logging already within UniPort method
1924 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001926 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001927 }
1928 }
1929}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001930
mpagenko3af1f032020-06-10 08:53:41 +00001931// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001933 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301934 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001935 // with following remark:
1936 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1937 // # load on the core
1938
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001939 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001940
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001941 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001942 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301943 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301945 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001946 if !dh.reconciling {
1947 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 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 +00001949 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001950 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001952 }
mpagenko3af1f032020-06-10 08:53:41 +00001953 }
1954 }
1955}
1956
1957// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001959 // compare enableUniPortStateUpdate() above
1960 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1961 for uniNo, uniPort := range dh.uniEntityMap {
1962 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301963 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301965 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001966 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 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 +00001968 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001969 }
1970}
1971
1972// ONU_Active/Inactive announcement on system KAFKA bus
1973// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001975 var de voltha.DeviceEvent
1976 eventContext := make(map[string]string)
1977 //Populating event context
1978 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001980 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301982 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001983 }
1984 oltSerialNumber := parentDevice.SerialNumber
1985
1986 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1987 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1988 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05301989 eventContext["olt-serial-number"] = oltSerialNumber
1990 eventContext["device-id"] = aDeviceID
1991 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001993 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001994
1995 /* Populating device event body */
1996 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301997 de.ResourceId = aDeviceID
1998 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001999 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2000 de.Description = fmt.Sprintf("%s Event - %s - %s",
2001 cEventObjectType, cOnuActivatedEvent, "Raised")
2002 } else {
2003 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2004 de.Description = fmt.Sprintf("%s Event - %s - %s",
2005 cEventObjectType, cOnuActivatedEvent, "Cleared")
2006 }
2007 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2009 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302010 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002011 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002012 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302013 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002014}
2015
Himani Chawla4d908332020-08-31 12:30:20 +05302016// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002017func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002018 chLSFsm := make(chan Message, 2048)
2019 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302020 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002022 sFsmName = "LockStateFSM"
2023 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002025 sFsmName = "UnLockStateFSM"
2026 }
mpagenko3af1f032020-06-10 08:53:41 +00002027
dbainbri4d3a0dc2020-12-02 00:33:42 +00002028 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002029 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002030 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002031 return
2032 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002034 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002035 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302036 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002037 dh.pLockStateFsm = pLSFsm
2038 } else {
2039 dh.pUnlockStateFsm = pLSFsm
2040 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002042 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002044 }
2045}
2046
2047// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002049 /* Uni Port lock/unlock procedure -
2050 ***** should run via 'adminDone' state and generate the argument requested event *****
2051 */
2052 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302053 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002054 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2055 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2056 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002057 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302058 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002059 }
2060 } else {
2061 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2062 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2063 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002064 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302065 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002066 }
2067 }
2068 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002069 if pLSStatemachine.Is(uniStDisabled) {
2070 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002072 // maybe try a FSM reset and then again ... - TODO!!!
2073 } else {
2074 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002075 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002076 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002077 }
2078 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002080 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002081 // maybe try a FSM reset and then again ... - TODO!!!
2082 }
2083 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002085 // maybe try a FSM reset and then again ... - TODO!!!
2086 }
2087}
2088
Himani Chawla6d2ae152020-09-02 13:11:20 +05302089//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002090func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002091
2092 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002093 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002094 kvbackend := &db.Backend{
2095 Client: dh.pOpenOnuAc.kvClient,
2096 StoreType: dh.pOpenOnuAc.KVStoreType,
2097 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002098 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002099 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2100 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002101
mpagenkoaf801632020-07-03 10:00:42 +00002102 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002103}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302105 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002106
mpagenkodff5dda2020-08-28 11:52:01 +00002107 for _, field := range flow.GetOfbFields(apFlowItem) {
2108 switch field.Type {
2109 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2110 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002112 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2113 }
mpagenko01e726e2020-10-23 09:45:29 +00002114 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002115 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2116 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302117 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002118 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302119 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2120 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002121 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2122 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002123 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2124 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 return
mpagenkodff5dda2020-08-28 11:52:01 +00002126 }
2127 }
mpagenko01e726e2020-10-23 09:45:29 +00002128 */
mpagenkodff5dda2020-08-28 11:52:01 +00002129 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2130 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302131 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002132 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302133 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002134 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302135 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002136 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302138 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002139 }
2140 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2141 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002143 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002144 "PCP": loAddPcp})
2145 }
2146 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2147 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002149 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2150 }
2151 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2152 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002154 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2155 }
2156 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2157 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002159 "IPv4-DST": field.GetIpv4Dst()})
2160 }
2161 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2162 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002164 "IPv4-SRC": field.GetIpv4Src()})
2165 }
2166 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2167 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002168 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002169 "Metadata": field.GetTableMetadata()})
2170 }
2171 /*
2172 default:
2173 {
2174 //all other entires ignored
2175 }
2176 */
2177 }
2178 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302179}
mpagenkodff5dda2020-08-28 11:52:01 +00002180
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002182 for _, action := range flow.GetActions(apFlowItem) {
2183 switch action.Type {
2184 /* not used:
2185 case of.OfpActionType_OFPAT_OUTPUT:
2186 {
mpagenko01e726e2020-10-23 09:45:29 +00002187 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002188 "Output": action.GetOutput()})
2189 }
2190 */
2191 case of.OfpActionType_OFPAT_PUSH_VLAN:
2192 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002194 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2195 }
2196 case of.OfpActionType_OFPAT_SET_FIELD:
2197 {
2198 pActionSetField := action.GetSetField()
2199 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002201 "OxcmClass": pActionSetField.Field.OxmClass})
2202 }
2203 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302204 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302206 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002207 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302210 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002211 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002213 "Type": pActionSetField.Field.GetOfbField().Type})
2214 }
2215 }
2216 /*
2217 default:
2218 {
2219 //all other entires ignored
2220 }
2221 */
2222 }
2223 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302224}
2225
2226//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302228 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2229 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2230 var loAddPcp, loSetPcp uint8
2231 var loIPProto uint32
2232 /* the TechProfileId is part of the flow Metadata - compare also comment within
2233 * OLT-Adapter:openolt_flowmgr.go
2234 * Metadata 8 bytes:
2235 * Most Significant 2 Bytes = Inner VLAN
2236 * Next 2 Bytes = Tech Profile ID(TPID)
2237 * Least Significant 4 Bytes = Port ID
2238 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2239 * subscriber related flows.
2240 */
2241
dbainbri4d3a0dc2020-12-02 00:33:42 +00002242 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302243 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302245 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002246 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302247 }
mpagenko551a4d42020-12-08 18:09:20 +00002248 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002249 loCookie := apFlowItem.GetCookie()
2250 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002251 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002252 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302253
dbainbri4d3a0dc2020-12-02 00:33:42 +00002254 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002255 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302256 if loIPProto == 2 {
2257 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2258 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002259 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2260 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302261 return nil
2262 }
mpagenko01e726e2020-10-23 09:45:29 +00002263 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002265
2266 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002267 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002268 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2269 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2270 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2271 //TODO!!: Use DeviceId within the error response to rwCore
2272 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002273 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002274 }
2275 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002277 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2278 } else {
2279 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2280 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2281 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302282 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002283 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002285 }
mpagenko9a304ea2020-12-16 15:54:01 +00002286
2287 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2288 dh.lockVlanConfig.Lock()
2289 defer dh.lockVlanConfig.Unlock()
2290 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302291 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002293 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002294 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002295 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002296 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002297}
2298
2299//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002300func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002301 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2302 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2303 //no extra check is done on the rule parameters
2304 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2305 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2306 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2307 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002308 // - 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 +00002309 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002311
2312 /* TT related temporary workaround - should not be needed anymore
2313 for _, field := range flow.GetOfbFields(apFlowItem) {
2314 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2315 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002316 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002317 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2318 if loIPProto == 2 {
2319 // 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 +00002320 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002321 log.Fields{"device-id": dh.deviceID})
2322 return nil
2323 }
2324 }
2325 } //for all OfbFields
2326 */
2327
mpagenko9a304ea2020-12-16 15:54:01 +00002328 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2329 dh.lockVlanConfig.Lock()
2330 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002331 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002333 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002335 log.Fields{"device-id": dh.deviceID})
2336 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002337 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002338 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002339
mpagenko01e726e2020-10-23 09:45:29 +00002340 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002341}
2342
Himani Chawla26e555c2020-08-31 12:30:20 +05302343// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002344// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002345func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002346 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002347 chVlanFilterFsm := make(chan Message, 2048)
2348
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002350 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002351 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302352 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002353 }
2354
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002356 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2357 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002358 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302359 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002360 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2361 if pVlanFilterStatemachine != nil {
2362 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2363 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302365 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002366 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302367 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2370 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002371 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002372 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002373 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002375 }
2376 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002377 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002378 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002380 }
2381 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002383 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302384 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002385 }
2386 return nil
2387}
2388
mpagenkofc4f56e2020-11-04 17:17:49 +00002389//VerifyVlanConfigRequest checks on existence of a given uniPort
2390// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002391func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002392 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2393 var pCurrentUniPort *onuUniPort
2394 for _, uniPort := range dh.uniEntityMap {
2395 // only if this port is validated for operState transfer
2396 if uniPort.uniID == uint8(aUniID) {
2397 pCurrentUniPort = uniPort
2398 break //found - end search loop
2399 }
2400 }
2401 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002402 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002403 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2404 return
2405 }
mpagenko551a4d42020-12-08 18:09:20 +00002406 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002407}
2408
mpagenkodff5dda2020-08-28 11:52:01 +00002409//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002410func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002411 //TODO!! verify and start pending flow configuration
2412 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2413 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302414 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002415 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2416 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2417 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002418 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2419 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2420 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2421 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2422 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2423 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2424 } else {
2425 /***** UniVlanConfigFsm continued */
2426 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2427 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2428 "UniPort": apUniPort.portNo})
2429 }
2430 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2431 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2432 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2433 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2434 } else {
2435 /***** UniVlanConfigFsm continued */
2436 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2437 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2438 "UniPort": apUniPort.portNo})
2439 }
mpagenkodff5dda2020-08-28 11:52:01 +00002440 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002441 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2442 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002443 "UniPort": apUniPort.portNo})
2444 }
2445 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002446 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2447 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2448 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002449 }
2450 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002452 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002453 }
mpagenkodff5dda2020-08-28 11:52:01 +00002454 } // else: nothing to do
2455}
2456
2457//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2458// 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 +00002459func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2460 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002461 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2462 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302463 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002464}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002465
Girish Gowdra26a40922021-01-29 17:14:34 -08002466//ProcessPendingTpDelete processes any pending TP delete (if available)
2467func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2468 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2469 if apUniPort == nil {
2470 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2471 return
2472 }
2473 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2474 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2475 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2476 if pAniConfigStatemachine != nil {
2477 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2478 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2479 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2480 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2481 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2482 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2483 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2484 return
2485 }
2486 } else {
2487 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2488 return
2489 }
2490 }
2491 return
2492 }
2493}
2494
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002495//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2496//available for potential reconcilement
2497
dbainbri4d3a0dc2020-12-02 00:33:42 +00002498func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002499
2500 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002502 return nil
2503 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002504 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002505
dbainbri4d3a0dc2020-12-02 00:33:42 +00002506 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002507 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002509 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2510 }
2511 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2512
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002513 // deadline context to ensure completion of background routines waited for
2514 //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 +05302515 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002516 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2517
2518 pDevEntry.resetKvProcessingErrorIndication()
2519 var wg sync.WaitGroup
2520 wg.Add(1) // for the 1 go routine to finish
2521
dbainbri4d3a0dc2020-12-02 00:33:42 +00002522 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2523 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002524
2525 return pDevEntry.getKvProcessingErrorIndication()
2526}
2527
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002529 defer cancel() //ensure termination of context (may be pro forma)
2530 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002531 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002532 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002533}
2534
dbainbri4d3a0dc2020-12-02 00:33:42 +00002535func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002536
2537 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002538 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002539 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2541 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002542 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002543 return err
2544 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002546 return nil
2547 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002548 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002549 return nil
2550}
2551
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2553 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002554 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002555 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002556 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2557 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002558 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2559 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2560
2561 pDevEntry.resetKvProcessingErrorIndication()
2562 var wg sync.WaitGroup
2563 wg.Add(1) // for the 1 go routine to finish
2564
2565 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002567
2568 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002570 return err
2571 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002572 return nil
2573}
2574
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002575func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2576 var errStr string = ""
2577 for _, err := range errS {
2578 if err != nil {
2579 errStr = errStr + err.Error() + " "
2580 }
2581 }
2582 if errStr != "" {
2583 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2584 }
2585 return nil
2586}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002587
2588// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2589func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2590 dh.lockDevice.RLock()
2591 defer dh.lockDevice.RUnlock()
2592 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2593 return uniPort.entityID, nil
2594 }
2595 return 0, errors.New("error-fetching-uni-port")
2596}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002597
2598// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002599func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2600 var errorsList []error
2601 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 -08002602
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002603 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2604 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2605 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2606
2607 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2608 // successfully.
2609 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2610 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2611 if len(errorsList) > 0 {
2612 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2613 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002614 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002615 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2616 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002617}
2618
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002619func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2620 var err error
2621 var errorsList []error
2622 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2623
2624 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2625 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2626 errorsList = append(errorsList, err)
2627 }
2628 }
2629
2630 return errorsList
2631}
2632
2633func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2634 var err error
2635 var errorsList []error
2636 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2637 // Check if group metric related config is updated
2638 for _, v := range pmConfigs.Groups {
2639 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2640 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2641 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2642
2643 if ok && m.frequency != v.GroupFreq {
2644 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2645 errorsList = append(errorsList, err)
2646 }
2647 }
2648 if ok && m.enabled != v.Enabled {
2649 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2650 errorsList = append(errorsList, err)
2651 }
2652 }
2653 }
2654 return errorsList
2655}
2656
2657func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2658 var err error
2659 var errorsList []error
2660 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2661 // Check if standalone metric related config is updated
2662 for _, v := range pmConfigs.Metrics {
2663 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002664 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002665 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2666
2667 if ok && m.frequency != v.SampleFreq {
2668 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2669 errorsList = append(errorsList, err)
2670 }
2671 }
2672 if ok && m.enabled != v.Enabled {
2673 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2674 errorsList = append(errorsList, err)
2675 }
2676 }
2677 }
2678 return errorsList
2679}
2680
2681// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002682func (dh *deviceHandler) startCollector(ctx context.Context) {
2683 logger.Debugf(ctx, "startingCollector")
2684
2685 // Start routine to process OMCI GET Responses
2686 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002687 // Initialize the next metric collection time.
2688 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2689 // reset like onu rebooted.
2690 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002691 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002692 for {
2693 select {
2694 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002695 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002696 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002697 // Stop the L2 PM FSM
2698 go func() {
2699 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2700 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2701 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2702 }
2703 } else {
2704 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2705 }
2706 }()
2707
Girish Gowdrae09a6202021-01-12 18:10:59 -08002708 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002709 dh.pOnuMetricsMgr.stopTicks <- true
2710
Girish Gowdrae09a6202021-01-12 18:10:59 -08002711 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002712 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2713 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2714 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2715 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2716 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002717 // Update the next metric collection time.
2718 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002719 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002720 } else {
2721 if dh.pmConfigs.Grouped { // metrics are managed as a group
2722 // parse through the group and standalone metrics to see it is time to collect their metrics
2723 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002724
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002725 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2726 // 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 -08002727 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2728 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002729 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2730 }
2731 }
2732 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2733 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2734 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2735 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2736 }
2737 }
2738 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2739
2740 // parse through the group and update the next metric collection time
2741 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2742 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2743 // 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 -08002744 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2745 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002746 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2747 }
2748 }
2749 // parse through the standalone metrics and update the next metric collection time
2750 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2751 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2752 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2753 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2754 }
2755 }
2756 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2757 } /* else { // metrics are not managed as a group
2758 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2759 } */
2760 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002761 }
2762 }
2763}
kesavandfdf77632021-01-26 23:40:33 -05002764
2765func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2766
2767 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2768 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2769}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002770
2771func (dh *deviceHandler) isFsmInState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2772 var currentState string
2773 if pFsm != nil {
2774 currentState = pFsm.Current()
2775 if currentState == wantedState {
2776 return true
2777 }
2778 } else {
2779 logger.Warnw(ctx, "FSM not defined!", log.Fields{"wantedState": wantedState, "device-id": dh.deviceID})
2780 }
2781 return false
2782}
2783
2784func (dh *deviceHandler) mibUploadFsmInIdleState(ctx context.Context, idleState string) bool {
2785 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibUploadFsm.pFsm, idleState)
2786}
2787
2788func (dh *deviceHandler) mibDownloadFsmInIdleState(ctx context.Context, idleState string) bool {
2789 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibDownloadFsm.pFsm, idleState)
2790}
2791
2792func (dh *deviceHandler) devUniLockFsmInIdleState(ctx context.Context, idleState string) bool {
2793 return dh.isFsmInState(ctx, dh.pLockStateFsm.pAdaptFsm.pFsm, idleState)
2794}
2795
2796func (dh *deviceHandler) devUniUnlockFsmInIdleState(ctx context.Context, idleState string) bool {
2797 return dh.isFsmInState(ctx, dh.pUnlockStateFsm.pAdaptFsm.pFsm, idleState)
2798}
2799
2800func (dh *deviceHandler) devAniConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2801 if dh.pOnuTP.pAniConfigFsm != nil {
2802 for _, v := range dh.pOnuTP.pAniConfigFsm {
2803 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2804 return false
2805 }
2806 }
2807 return true
2808 }
2809 logger.Warnw(ctx, "AniConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2810 return false
2811}
2812
2813func (dh *deviceHandler) devUniVlanConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2814 if dh.UniVlanConfigFsmMap != nil {
2815 for _, v := range dh.UniVlanConfigFsmMap {
2816 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2817 return false
2818 }
2819 }
2820 return true
2821 }
2822 logger.Warnw(ctx, "UniVlanConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2823 return false
2824}
2825
Girish Gowdrae0140f02021-02-02 16:55:09 -08002826func (dh *deviceHandler) l2PmFsmInIdleState(ctx context.Context, idleState string) bool {
2827 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2828 return dh.isFsmInState(ctx, dh.pOnuMetricsMgr.pAdaptFsm.pFsm, idleState)
2829 }
2830 logger.Warnw(ctx, "L2 PM FSM not defined!", log.Fields{"device-id": dh.deviceID})
2831 return false
2832}
2833
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002834func (dh *deviceHandler) allButCallingFsmInIdleState(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
2835 for fsmName, fsmStruct := range fsmIdleStateFuncMap {
2836 if fsmName != callingFsm && !fsmStruct.idleCheckFunc(dh, ctx, fsmStruct.idleState) {
2837 return false
2838 }
2839 }
2840 return true
2841}
2842
2843func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
2844 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
2845 if err := dh.resetFsms(ctx, false); err != nil {
2846 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
2847 // TODO: fatal error reset ONU, delete deviceHandler!
2848 return
2849 }
2850 if !dh.getCollectorIsRunning() {
2851 // Start PM collector routine
2852 go dh.startCollector(ctx)
2853 }
2854 dh.uniEntityMap = make(map[uint32]*onuUniPort)
2855 dh.reconciling = true
2856}
2857
2858func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
2859 dh.mutexCollectorFlag.Lock()
2860 dh.collectorIsRunning = flagValue
2861 dh.mutexCollectorFlag.Unlock()
2862}
2863
2864func (dh *deviceHandler) getCollectorIsRunning() bool {
2865 dh.mutexCollectorFlag.RLock()
2866 flagValue := dh.collectorIsRunning
2867 dh.mutexCollectorFlag.RUnlock()
2868 return flagValue
2869}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302870
2871func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
2872 logger.Debugf(ctx, "startingAlarmManager")
2873
2874 // Start routine to process OMCI GET Responses
2875 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
2876 if stop := <-dh.stopAlarmManager; stop {
2877 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2878 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any
2879 }
2880}