blob: c452fe5b6ff235187da180f4a27d3bcb17cd4a2a [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)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +000094const (
95 cReconcilingTimeout = 10 //seconds
96)
Holger Hildebrandt24d51952020-05-04 14:03:42 +000097
Holger Hildebrandt10d98192021-01-27 15:29:31 +000098type usedOmciConfigFsms int
99
100const (
101 cUploadFsm usedOmciConfigFsms = iota
102 cDownloadFsm
103 cUniLockFsm
104 cUniUnLockFsm
105 cAniConfigFsm
106 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800107 cL2PmFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000108)
109
110type idleCheckStruct struct {
111 idleCheckFunc func(*deviceHandler, context.Context, string) bool
112 idleState string
113}
114
115var fsmIdleStateFuncMap = map[usedOmciConfigFsms]idleCheckStruct{
116 cUploadFsm: {(*deviceHandler).mibUploadFsmInIdleState, cMibUlFsmIdleState},
117 cDownloadFsm: {(*deviceHandler).mibDownloadFsmInIdleState, cMibDlFsmIdleState},
118 cUniLockFsm: {(*deviceHandler).devUniLockFsmInIdleState, cUniFsmIdleState},
119 cUniUnLockFsm: {(*deviceHandler).devUniUnlockFsmInIdleState, cUniFsmIdleState},
120 cAniConfigFsm: {(*deviceHandler).devAniConfigFsmInIdleState, cAniFsmIdleState},
121 cUniVlanConfigFsm: {(*deviceHandler).devUniVlanConfigFsmInIdleState, cVlanFsmIdleState},
Girish Gowdrae0140f02021-02-02 16:55:09 -0800122 cL2PmFsm: {(*deviceHandler).l2PmFsmInIdleState, cL2PmFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000125const (
126 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000127 drUnset = 0
128 drActivatingOnu = 1
129 drStartingOpenomci = 2
130 drDiscoveryMibsyncComplete = 3
131 drInitialMibDownloaded = 4
132 drTechProfileConfigDownloadSuccess = 5
133 drOmciFlowsPushed = 6
134 drOmciAdminLock = 7
135 drOnuReenabled = 8
136 drStoppingOpenomci = 9
137 drRebooting = 10
138 drOmciFlowsDeleted = 11
139 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000140)
141
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000142var deviceReasonMap = map[uint8]string{
143 drUnset: "unset",
144 drActivatingOnu: "activating-onu",
145 drStartingOpenomci: "starting-openomci",
146 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
147 drInitialMibDownloaded: "initial-mib-downloaded",
148 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
149 drOmciFlowsPushed: "omci-flows-pushed",
150 drOmciAdminLock: "omci-admin-lock",
151 drOnuReenabled: "onu-reenabled",
152 drStoppingOpenomci: "stopping-openomci",
153 drRebooting: "rebooting",
154 drOmciFlowsDeleted: "omci-flows-deleted",
155 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
156}
157
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158//deviceHandler will interact with the ONU ? device.
159type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160 deviceID string
161 DeviceType string
162 adminState string
163 device *voltha.Device
164 logicalDeviceID string
165 ProxyAddressID string
166 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530167 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000168 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000169
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000170 coreProxy adapterif.CoreProxy
171 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530172 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000173
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800174 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800175
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000176 pOpenOnuAc *OpenONUAC
177 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530178 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000179 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530181 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800182 pOnuMetricsMgr *onuMetricsManager
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530183 pAlarmMgr *onuAlarmManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184 exitChannel chan int
185 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000186 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000187 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530188 pLockStateFsm *lockStateFsm
189 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000191 //flowMgr *OpenOltFlowMgr
192 //eventMgr *OpenOltEventMgr
193 //resourceMgr *rsrcMgr.OpenOltResourceMgr
194
195 //discOnus sync.Map
196 //onus sync.Map
197 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000198 collectorIsRunning bool
199 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000200 stopCollector chan bool
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530201 alarmManagerIsRunning bool
202 mutextAlarmManagerFlag sync.RWMutex
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530203 stopAlarmManager chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000204 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000205 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000206 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000207 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
208 reconciling bool
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000209 mutexReconcilingFlag sync.RWMutex
210 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
mpagenkofc4f56e2020-11-04 17:17:49 +0000211 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000212}
213
Himani Chawla6d2ae152020-09-02 13:11:20 +0530214//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530215func 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 +0530216 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000217 dh.coreProxy = cp
218 dh.AdapterProxy = ap
219 dh.EventProxy = ep
220 cloned := (proto.Clone(device)).(*voltha.Device)
221 dh.deviceID = cloned.Id
222 dh.DeviceType = cloned.Type
223 dh.adminState = "up"
224 dh.device = cloned
225 dh.pOpenOnuAc = adapter
226 dh.exitChannel = make(chan int, 1)
227 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000228 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000229 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530231 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530232 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 dh.stopHeartbeatCheck = make(chan bool, 2)
234 //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 +0000235 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530236 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000237 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000238 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000239 dh.reconciling = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000240 dh.chReconcilingFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000241 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800243 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
244 dh.pmConfigs = cloned.PmConfigs
245 } /* else {
246 // will be populated when onu_metrics_mananger is initialized.
247 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800248
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 // Device related state machine
250 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000251 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000253 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
254 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
255 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
256 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
257 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 },
259 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000260 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
261 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
262 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
263 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
264 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
265 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
266 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
267 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 },
269 )
mpagenkoaf801632020-07-03 10:00:42 +0000270
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000271 return &dh
272}
273
Himani Chawla6d2ae152020-09-02 13:11:20 +0530274// start save the device to the data model
275func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000276 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279}
280
Himani Chawla4d908332020-08-31 12:30:20 +0530281/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000282// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530283func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284 logger.Debug("stopping-device-handler")
285 dh.exitChannel <- 1
286}
Himani Chawla4d908332020-08-31 12:30:20 +0530287*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288
289// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530290// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291
Girish Gowdrae0140f02021-02-02 16:55:09 -0800292//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530293func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000297 if dh.pDeviceStateFsm.Is(devStNull) {
298 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800302 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
303 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800304 // Now, set the initial PM configuration for that device
305 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
306 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
307 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800308 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 }
312
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313}
314
mpagenko057889c2021-01-21 16:51:58 +0000315func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530316 msgBody := msg.GetBody()
317 omciMsg := &ic.InterAdapterOmciMessage{}
318 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530320 "device-id": dh.deviceID, "error": err})
321 return err
322 }
323
324 //assuming omci message content is hex coded!
325 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
328 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530330 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000331 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000333 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000334 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 +0530335 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000337 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530338}
339
Himani Chawla6d2ae152020-09-02 13:11:20 +0530340func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000341 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000343
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000345
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000347 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000349 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
350 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 if dh.pOnuTP == nil {
352 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000355 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000357 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000359 "device-state": deviceReasonMap[dh.deviceReason]})
360 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000362 //previous state test here was just this one, now extended for more states to reject the SetRequest:
363 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
364 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530365
366 msgBody := msg.GetBody()
367 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
368 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530370 "device-id": dh.deviceID, "error": err})
371 return err
372 }
373
374 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
376 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379
380 if techProfMsg.UniId > 255 {
381 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
382 techProfMsg.UniId, dh.deviceID))
383 }
384 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800385 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
386 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000387 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800388 return err
389 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 // if there has been some change for some uni TechProfilePath
393 //in order to allow concurrent calls to other dh instances we do not wait for execution here
394 //but doing so we can not indicate problems to the caller (who does what with that then?)
395 //by now we just assume straightforward successful execution
396 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
397 // possible problems to the caller later autonomously
398
399 // deadline context to ensure completion of background routines waited for
400 //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 +0530401 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530402 dctx, cancel := context.WithDeadline(context.Background(), deadline)
403
Girish Gowdra041dcb32020-11-16 16:54:30 -0800404 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 pDevEntry.resetKvProcessingErrorIndication()
406
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 var wg sync.WaitGroup
408 wg.Add(2) // for the 2 go routines to finish
409 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000410 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
411 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
412 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
Girish Gowdra041dcb32020-11-16 16:54:30 -0800414 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000416 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530417 return nil
418}
419
Himani Chawla6d2ae152020-09-02 13:11:20 +0530420func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 msg *ic.InterAdapterMessage) error {
423
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000425
dbainbri4d3a0dc2020-12-02 00:33:42 +0000426 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000427 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000429 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
430 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 if dh.pOnuTP == nil {
432 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530434 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000435 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530436 }
437
438 msgBody := msg.GetBody()
439 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
440 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000441 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530442 "device-id": dh.deviceID, "error": err})
443 return err
444 }
445
446 //compare TECH_PROFILE_DOWNLOAD_REQUEST
447 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530449
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450 if delGemPortMsg.UniId > 255 {
451 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
452 delGemPortMsg.UniId, dh.deviceID))
453 }
454 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800455 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
456 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000457 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 -0800458 return err
459 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530460
mpagenkofc4f56e2020-11-04 17:17:49 +0000461 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000462
mpagenkofc4f56e2020-11-04 17:17:49 +0000463 // deadline context to ensure completion of background routines waited for
464 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
465 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466
Girish Gowdra041dcb32020-11-16 16:54:30 -0800467 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000468
mpagenkofc4f56e2020-11-04 17:17:49 +0000469 var wg sync.WaitGroup
470 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000471 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000472 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000474
Girish Gowdra041dcb32020-11-16 16:54:30 -0800475 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530476}
477
Himani Chawla6d2ae152020-09-02 13:11:20 +0530478func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000483
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
488 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 if dh.pOnuTP == nil {
490 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 }
495
496 msgBody := msg.GetBody()
497 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
498 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 "device-id": dh.deviceID, "error": err})
501 return err
502 }
503
504 //compare TECH_PROFILE_DOWNLOAD_REQUEST
505 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507
508 if delTcontMsg.UniId > 255 {
509 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
510 delTcontMsg.UniId, dh.deviceID))
511 }
512 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800513 tpPath := delTcontMsg.TpPath
514 tpID, err := GetTpIDFromTpPath(tpPath)
515 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000516 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800517 return err
518 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519
dbainbri4d3a0dc2020-12-02 00:33:42 +0000520 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530521 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530522 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530523 dctx, cancel := context.WithDeadline(context.Background(), deadline)
524
Girish Gowdra041dcb32020-11-16 16:54:30 -0800525 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 pDevEntry.resetKvProcessingErrorIndication()
527
Himani Chawla26e555c2020-08-31 12:30:20 +0530528 var wg sync.WaitGroup
529 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 cResourceTcont, delTcontMsg.AllocId, &wg)
532 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
534 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000535
Girish Gowdra041dcb32020-11-16 16:54:30 -0800536 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530537 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530538 return nil
539}
540
Himani Chawla6d2ae152020-09-02 13:11:20 +0530541//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000542// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
543// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000544func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000545 msgID := msg.Header.Id
546 msgType := msg.Header.Type
547 fromTopic := msg.Header.FromTopic
548 toTopic := msg.Header.ToTopic
549 toDeviceID := msg.Header.ToDeviceId
550 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000552 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
553
554 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000555 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000556 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
557 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000558 {
mpagenko057889c2021-01-21 16:51:58 +0000559 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000560 }
mpagenkoaf801632020-07-03 10:00:42 +0000561 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
562 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000564 }
565 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
566 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000567 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000568
mpagenkoaf801632020-07-03 10:00:42 +0000569 }
570 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
571 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000573 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000574 default:
575 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000577 "msgType": msg.Header.Type, "device-id": dh.deviceID})
578 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000579 }
580 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000581}
582
mpagenkodff5dda2020-08-28 11:52:01 +0000583//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000584func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
585 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000586 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000588
mpagenko01e726e2020-10-23 09:45:29 +0000589 var retError error = nil
590 //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 +0000591 if apOfFlowChanges.ToRemove != nil {
592 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000593 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000594 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000595 "device-id": dh.deviceID})
596 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000597 continue
598 }
599 flowInPort := flow.GetInPort(flowItem)
600 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000601 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 +0000602 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
603 continue
604 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000605 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000606 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000608 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000609 continue
610 } else {
611 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530612 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000613 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
614 loUniPort = uniPort
615 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000617 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
618 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
619 flowInPort, dh.deviceID)
620 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000621 }
622 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000624 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000625 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000627 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000628 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000630 log.Fields{"device-id": dh.deviceID, "error": err})
631 retError = err
632 continue
633 //return err
634 } else { // if last setting succeeds, overwrite possibly previously set error
635 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000636 }
637 }
638 }
639 }
mpagenko01e726e2020-10-23 09:45:29 +0000640 if apOfFlowChanges.ToAdd != nil {
641 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
642 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000644 "device-id": dh.deviceID})
645 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
646 continue
647 }
648 flowInPort := flow.GetInPort(flowItem)
649 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 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 +0000651 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
652 continue
653 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
654 } else if flowInPort == dh.ponPortNumber {
655 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000657 "device-id": dh.deviceID, "inPort": flowInPort})
658 continue
659 } else {
660 // this is the relevant upstream flow
661 var loUniPort *onuUniPort
662 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
663 loUniPort = uniPort
664 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000666 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
667 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
668 flowInPort, dh.deviceID)
669 continue
670 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
671 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
673 // if not, we just throw some error here to have an indication about that, if we really need to support that
674 // then we would need to create some means to activate the internal stored flows
675 // after the device gets active automatically (and still with its dependency to the TechProfile)
676 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
677 // also abort for the other still possible flows here
678 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000680 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000681 return fmt.Errorf("improper device state on device %s", dh.deviceID)
682 }
683
mpagenko01e726e2020-10-23 09:45:29 +0000684 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000686 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
687 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000689 //try next flow after processing error
690 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000692 log.Fields{"device-id": dh.deviceID, "error": err})
693 retError = err
694 continue
695 //return err
696 } else { // if last setting succeeds, overwrite possibly previously set error
697 retError = nil
698 }
699 }
700 }
701 }
702 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000703}
704
Himani Chawla6d2ae152020-09-02 13:11:20 +0530705//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000706//following are the expected device states after this activity:
707//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
708// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
710 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000711
mpagenko900ee4b2020-10-12 11:56:34 +0000712 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000713 //note that disableDevice sequences in some 'ONU active' state may yield also
714 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000715 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000716 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000717 //disable-device shall be just a UNi/ONU-G related admin state setting
718 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000719
mpagenkofc4f56e2020-11-04 17:17:49 +0000720 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000721 // disable UNI ports/ONU
722 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
723 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000725 } else { //LockStateFSM already init
726 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000728 }
729 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000731 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000733 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
734 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000736 }
mpagenko01e726e2020-10-23 09:45:29 +0000737 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000738
739 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000741 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300742 }
743}
744
Himani Chawla6d2ae152020-09-02 13:11:20 +0530745//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000746func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
747 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000748
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
750 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
751 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
752 // for real ONU's that should have nearly no influence
753 // Note that for real ONU's there is anyway a problematic situation with following sequence:
754 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
755 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
756 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
757 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
758
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000759 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000760 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000761 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000763 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000764 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000766 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300767}
768
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
770 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000771
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000773 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000775 return
776 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000778 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000780 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000782 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000783 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000784 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000785 }
Himani Chawla4d908332020-08-31 12:30:20 +0530786 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000787 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
788 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
789 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
790 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000792}
793
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
795 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000796
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000798 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000800 return
801 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000802 dh.pOnuTP.lockTpProcMutex()
803 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000804 pDevEntry.persUniConfigMutex.RLock()
805 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000806
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000807 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000809 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000810 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000811 return
812 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000813 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000814 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
815 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000817 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000818 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000819 return
820 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800821 for tpID := range uniData.PersTpPathMap {
822 // deadline context to ensure completion of background routines waited for
823 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
824 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000826
Girish Gowdra041dcb32020-11-16 16:54:30 -0800827 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
828 var wg sync.WaitGroup
829 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
831 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800832 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800834 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000835 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000836 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000838 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000839 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000840 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000841 }
842}
843
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
845 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000846
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000850 return
851 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000852 pDevEntry.persUniConfigMutex.RLock()
853 defer pDevEntry.persUniConfigMutex.RUnlock()
854
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000855 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000857 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000858 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000859 return
860 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000862 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
863 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000865 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000866 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000867 return
868 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000869 var uniPort *onuUniPort
870 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 return
875 }
876 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000878 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000879 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000881 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
882 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000887 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000888 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890 }
891 }
892 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000893 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000895 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000896 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000897 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898 }
899}
900
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
902 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 +0000903
904 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000905 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000906}
907
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
909 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000910
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000912 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000913 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000914 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000915 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000916 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000917
918 // deadline context to ensure completion of background routines waited for
919 //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 +0530920 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000921 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922
923 pDevEntry.resetKvProcessingErrorIndication()
924
925 var wg sync.WaitGroup
926 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
928 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000929
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000930 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000931 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000932}
933
dbainbri4d3a0dc2020-12-02 00:33:42 +0000934func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
935 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300936 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000938 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300939 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530941 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530943 return err
944 }
mpagenko01e726e2020-10-23 09:45:29 +0000945
946 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000948
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000950 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300952 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000953 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000954 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300955 return err
956 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000957 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300958 return err
959 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000960 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000961 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
962 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
963 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
964 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300965 return nil
966}
967
mpagenkoc8bba412021-01-15 15:38:44 +0000968//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
969func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
970 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
971 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000972 //return success to comfort the core processing during integration
973 return nil
974 // TODO!!: also verify error response behavior
975 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000976}
977
Himani Chawla6d2ae152020-09-02 13:11:20 +0530978// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000979// #####################################################################################
980
981// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530982// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000983
dbainbri4d3a0dc2020-12-02 00:33:42 +0000984func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
985 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 +0000986}
987
988// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000990
dbainbri4d3a0dc2020-12-02 00:33:42 +0000991 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000992 var err error
993
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000994 // populate what we know. rest comes later after mib sync
995 dh.device.Root = false
996 dh.device.Vendor = "OpenONU"
997 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000998 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000999 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001000
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001001 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001002
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001003 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001004 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1005 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301006 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001007 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001009 log.Fields{"device-id": dh.deviceID})
1010 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001011
Himani Chawla4d908332020-08-31 12:30:20 +05301012 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001013 dh.ponPortNumber = dh.device.ParentPortNo
1014
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001015 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1016 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1017 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001018 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001019 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301020 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001021
1022 /*
1023 self._pon = PonPort.create(self, self._pon_port_number)
1024 self._pon.add_peer(self.parent_id, self._pon_port_number)
1025 self.logger.debug('adding-pon-port-to-agent',
1026 type=self._pon.get_port().type,
1027 admin_state=self._pon.get_port().admin_state,
1028 oper_status=self._pon.get_port().oper_status,
1029 )
1030 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001031 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001032 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001033 var ponPortNo uint32 = 1
1034 if dh.ponPortNumber != 0 {
1035 ponPortNo = dh.ponPortNumber
1036 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001037
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001038 pPonPort := &voltha.Port{
1039 PortNo: ponPortNo,
1040 Label: fmt.Sprintf("pon-%d", ponPortNo),
1041 Type: voltha.Port_PON_ONU,
1042 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301043 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001044 PortNo: ponPortNo}}, // Peer port is parent's port number
1045 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1047 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001048 e.Cancel(err)
1049 return
1050 }
1051 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001052 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001053 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001055}
1056
1057// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001059
dbainbri4d3a0dc2020-12-02 00:33:42 +00001060 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001061 var err error
1062 /*
1063 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1064 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1065 return nil
1066 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1068 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069 e.Cancel(err)
1070 return
1071 }
1072
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001073 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001074 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001075 // reconcilement will be continued after mib download is done
1076 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001077
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001078 /*
1079 ############################################################################
1080 # Setup Alarm handler
1081 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1082 device.serial_number)
1083 ############################################################################
1084 # Setup PM configuration for this device
1085 # Pass in ONU specific options
1086 kwargs = {
1087 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1088 'heartbeat': self.heartbeat,
1089 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1090 }
1091 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1092 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1093 self.logical_device_id, device.serial_number,
1094 grouped=True, freq_override=False, **kwargs)
1095 pm_config = self._pm_metrics.make_proto()
1096 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1097 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1098 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1099
1100 # Note, ONU ID and UNI intf set in add_uni_port method
1101 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1102 ani_ports=[self._pon])
1103
1104 # Code to Run OMCI Test Action
1105 kwargs_omci_test_action = {
1106 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1107 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1108 }
1109 serial_number = device.serial_number
1110 self._test_request = OmciTestRequest(self.core_proxy,
1111 self.omci_agent, self.device_id,
1112 AniG, serial_number,
1113 self.logical_device_id,
1114 exclusive=False,
1115 **kwargs_omci_test_action)
1116
1117 self.enabled = True
1118 else:
1119 self.logger.info('onu-already-activated')
1120 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001121
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001123}
1124
1125// doStateConnected get the device info and update to voltha core
1126// for comparison of the original method (not that easy to uncomment): compare here:
1127// voltha-openolt-adapter/adaptercore/device_handler.go
1128// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 logger.Debug(ctx, "doStateConnected-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, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135}
1136
1137// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001138func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001139
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301141 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001142 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001143 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144
1145 /*
1146 // Synchronous call to update device state - this method is run in its own go routine
1147 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1148 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001149 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 +00001150 return err
1151 }
1152 return nil
1153 */
1154}
1155
1156// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001158
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001160 var err error
1161
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001162 device := dh.device
1163 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001164 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001166 e.Cancel(err)
1167 return
1168 }
1169
1170 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001171 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001172 /*
1173 // Update the all ports state on that device to disable
1174 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001175 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176 return er
1177 }
1178
1179 //Update the device oper state and connection status
1180 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1181 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1182 dh.device = cloned
1183
1184 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001185 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001186 return er
1187 }
1188
1189 //get the child device for the parent device
1190 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1191 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001192 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001193 return err
1194 }
1195 for _, onuDevice := range onuDevices.Items {
1196
1197 // Update onu state as down in onu adapter
1198 onuInd := oop.OnuIndication{}
1199 onuInd.OperState = "down"
1200 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1201 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1202 if er != nil {
1203 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001204 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001205 //Do not return here and continue to process other ONUs
1206 }
1207 }
1208 // * Discovered ONUs entries need to be cleared , since after OLT
1209 // is up, it starts sending discovery indications again* /
1210 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001211 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001212 return nil
1213 */
Himani Chawla4d908332020-08-31 12:30:20 +05301214 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001215 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001216 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001217}
1218
Himani Chawla6d2ae152020-09-02 13:11:20 +05301219// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001220// #################################################################################
1221
1222// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301223// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001224
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001225//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001227 dh.lockDevice.RLock()
1228 pOnuDeviceEntry := dh.pOnuOmciDevice
1229 if aWait && pOnuDeviceEntry == nil {
1230 //keep the read sema short to allow for subsequent write
1231 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001232 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001233 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1234 // so it might be needed to wait here for that event with some timeout
1235 select {
1236 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001238 return nil
1239 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001240 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001241 // if written now, we can return the written value without sema
1242 return dh.pOnuOmciDevice
1243 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001244 }
mpagenko3af1f032020-06-10 08:53:41 +00001245 dh.lockDevice.RUnlock()
1246 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001247}
1248
Himani Chawla6d2ae152020-09-02 13:11:20 +05301249//setOnuDeviceEntry sets the ONU device entry within the handler
1250func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301251 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001252 dh.lockDevice.Lock()
1253 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001254 dh.pOnuOmciDevice = apDeviceEntry
1255 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001256 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301257 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001258}
1259
Himani Chawla6d2ae152020-09-02 13:11:20 +05301260//addOnuDeviceEntry creates a new ONU device or returns the existing
1261func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001263
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001265 if deviceEntry == nil {
1266 /* costum_me_map in python code seems always to be None,
1267 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1268 /* also no 'clock' argument - usage open ...*/
1269 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001270 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001271 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001272 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301273 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001274 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301275 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001276 // fire deviceEntry ready event to spread to possibly waiting processing
1277 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001279 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001280 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001281 }
1282 // might be updated with some error handling !!!
1283 return nil
1284}
1285
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1287 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001288 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1289
1290 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001291
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001293 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001295 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1296 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001297 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298 if err := dh.storePersistentData(ctx); err != nil {
1299 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001300 log.Fields{"device-id": dh.deviceID, "err": err})
1301 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001302 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001303 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001304 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001305 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1306 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001307 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001308 }
1309 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001310 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001311 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001312
1313 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 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 +00001315 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001316 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001317 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001318 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001319 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1320 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1321 // 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 +00001322 // 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 +00001323 // so let's just try to keep it simple ...
1324 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001325 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001326 if err != nil || device == nil {
1327 //TODO: needs to handle error scenarios
1328 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1329 return errors.New("Voltha Device not found")
1330 }
1331 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001332
dbainbri4d3a0dc2020-12-02 00:33:42 +00001333 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001334 return err
mpagenko3af1f032020-06-10 08:53:41 +00001335 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001336
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001337 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001338
1339 /* this might be a good time for Omci Verify message? */
1340 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001342 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001343 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001344 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001345
1346 /* give the handler some time here to wait for the OMCi verification result
1347 after Timeout start and try MibUpload FSM anyway
1348 (to prevent stopping on just not supported OMCI verification from ONU) */
1349 select {
1350 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001352 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001353 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001354 }
1355
1356 /* In py code it looks earlier (on activate ..)
1357 # Code to Run OMCI Test Action
1358 kwargs_omci_test_action = {
1359 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1360 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1361 }
1362 serial_number = device.serial_number
1363 self._test_request = OmciTestRequest(self.core_proxy,
1364 self.omci_agent, self.device_id,
1365 AniG, serial_number,
1366 self.logical_device_id,
1367 exclusive=False,
1368 **kwargs_omci_test_action)
1369 ...
1370 # Start test requests after a brief pause
1371 if not self._test_request_started:
1372 self._test_request_started = True
1373 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1374 reactor.callLater(tststart, self._test_request.start_collector)
1375
1376 */
1377 /* which is then: in omci_test_request.py : */
1378 /*
1379 def start_collector(self, callback=None):
1380 """
1381 Start the collection loop for an adapter if the frequency > 0
1382
1383 :param callback: (callable) Function to call to collect PM data
1384 """
1385 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1386 if callback is None:
1387 callback = self.perform_test_omci
1388
1389 if self.lc is None:
1390 self.lc = LoopingCall(callback)
1391
1392 if self.default_freq > 0:
1393 self.lc.start(interval=self.default_freq / 10)
1394
1395 def perform_test_omci(self):
1396 """
1397 Perform the initial test request
1398 """
1399 ani_g_entities = self._device.configuration.ani_g_entities
1400 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1401 is not None else None
1402 self._entity_id = ani_g_entities_ids[0]
1403 self.logger.info('perform-test', entity_class=self._entity_class,
1404 entity_id=self._entity_id)
1405 try:
1406 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1407 result = yield self._device.omci_cc.send(frame)
1408 if not result.fields['omci_message'].fields['success_code']:
1409 self.logger.info('Self-Test Submitted Successfully',
1410 code=result.fields[
1411 'omci_message'].fields['success_code'])
1412 else:
1413 raise TestFailure('Test Failure: {}'.format(
1414 result.fields['omci_message'].fields['success_code']))
1415 except TimeoutError as e:
1416 self.deferred.errback(failure.Failure(e))
1417
1418 except Exception as e:
1419 self.logger.exception('perform-test-Error', e=e,
1420 class_id=self._entity_class,
1421 entity_id=self._entity_id)
1422 self.deferred.errback(failure.Failure(e))
1423
1424 */
1425
1426 // PM related heartbeat??? !!!TODO....
1427 //self._heartbeat.enabled = True
1428
mpagenko1cc3cb42020-07-27 15:24:38 +00001429 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1430 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1431 * 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 +05301432 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001433 */
1434 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001435 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001436 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001437 if pMibUlFsm.Is(ulStDisabled) {
1438 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 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 +00001440 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301441 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301443 //Determine ONU status and start/re-start MIB Synchronization tasks
1444 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001445 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301446 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 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 +00001448 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001449 }
Himani Chawla4d908332020-08-31 12:30:20 +05301450 } else {
1451 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001452 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 +00001453 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301454 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001456 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001457 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001458 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001459 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001460 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001461 }
1462 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001463 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001464 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001465 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001466
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001467 if !dh.getCollectorIsRunning() {
1468 // Start PM collector routine
1469 go dh.startCollector(ctx)
1470 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301471 if !dh.getAlarmManagerIsRunning() {
1472 go dh.startAlarmManager(ctx)
1473 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301474
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001475 return nil
1476}
1477
dbainbri4d3a0dc2020-12-02 00:33:42 +00001478func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001479 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001480 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001481 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001483
mpagenko900ee4b2020-10-12 11:56:34 +00001484 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1485 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1486 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001487 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001488 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001489 log.Fields{"device-id": dh.deviceID, "error": err})
1490 // abort: system behavior is just unstable ...
1491 return err
1492 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001493 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494 _ = 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 +00001495
1496 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1497 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1498 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001500 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001502 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001503 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001504 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001505
1506 //TODO!!! remove existing traffic profiles
1507 /* from py code, if TP's exist, remove them - not yet implemented
1508 self._tp = dict()
1509 # Let TP download happen again
1510 for uni_id in self._tp_service_specific_task:
1511 self._tp_service_specific_task[uni_id].clear()
1512 for uni_id in self._tech_profile_download_done:
1513 self._tech_profile_download_done[uni_id].clear()
1514 */
1515
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001517
mpagenkofc4f56e2020-11-04 17:17:49 +00001518 dh.ReadyForSpecificOmciConfig = false
1519
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001521 // abort: system behavior is just unstable ...
1522 return err
1523 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001524 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001525 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001526 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001527 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001528 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001530 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001531 // abort: system behavior is just unstable ...
1532 return err
1533 }
1534 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001535 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001536 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001537 return nil
1538}
1539
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001540func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001541 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1542 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1543 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1544 // and using the stop/reset event should never harm
1545
dbainbri4d3a0dc2020-12-02 00:33:42 +00001546 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001547 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001549 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1550 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001551 if includingMibSyncFsm {
1552 //the MibSync FSM might be active all the ONU-active time,
1553 // hence it must be stopped unconditionally
1554 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1555 if pMibUlFsm != nil {
1556 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1557 }
mpagenko900ee4b2020-10-12 11:56:34 +00001558 }
1559 //MibDownload may run
1560 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1561 if pMibDlFsm != nil {
1562 _ = pMibDlFsm.Event(dlEvReset)
1563 }
1564 //port lock/unlock FSM's may be active
1565 if dh.pUnlockStateFsm != nil {
1566 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1567 }
1568 if dh.pLockStateFsm != nil {
1569 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1570 }
1571 //techProfile related PonAniConfigFsm FSM may be active
1572 if dh.pOnuTP != nil {
1573 // should always be the case here
1574 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1575 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001576 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1577 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1578 }
mpagenko900ee4b2020-10-12 11:56:34 +00001579 }
1580 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001581 // reset the possibly existing VlanConfigFsm
1582 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1583 //VlanFilterFsm exists and was already started
1584 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1585 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001586 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001587 // no need to remove specific data
1588 pVlanFilterFsm.RequestClearPersistency(false)
1589 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001590 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1591 }
1592 }
1593 }
1594 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001595 if dh.getCollectorIsRunning() {
1596 // Stop collector routine
1597 dh.stopCollector <- true
1598 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301599 if dh.getAlarmManagerIsRunning() {
1600 dh.stopAlarmManager <- true
1601 }
1602
mpagenko900ee4b2020-10-12 11:56:34 +00001603 return nil
1604}
1605
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1607 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 +05301608
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001609 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001611 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001613 return
1614 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001615 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001616 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1617 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1618 for _, mgmtEntityID := range pptpInstKeys {
1619 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1620 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301622 i++
1623 }
1624 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301626 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001627 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1628 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301629 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001630 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301631 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001632 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301633 i++
1634 }
1635 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301637 }
1638 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301640 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001641 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1642 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1643 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1644 * disable/enable toggling here to allow traffic
1645 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1646 * like the py comment says:
1647 * # start by locking all the unis till mib sync and initial mib is downloaded
1648 * # this way we can capture the port down/up events when we are ready
1649 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301650
mpagenkoa40e99a2020-11-17 13:50:39 +00001651 // Init Uni Ports to Admin locked state
1652 // *** should generate UniLockStateDone event *****
1653 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001655 } else { //LockStateFSM already init
1656 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001658 }
1659}
1660
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1662 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301663 /* Mib download procedure -
1664 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1665 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001667 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001669 return
1670 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301671 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1672 if pMibDlFsm != nil {
1673 if pMibDlFsm.Is(dlStDisabled) {
1674 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 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 +05301676 // maybe try a FSM reset and then again ... - TODO!!!
1677 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301679 // maybe use more specific states here for the specific download steps ...
1680 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301682 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301684 //Begin MIB data download (running autonomously)
1685 }
1686 }
1687 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001689 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301690 // maybe try a FSM reset and then again ... - TODO!!!
1691 }
1692 /***** Mib download started */
1693 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301695 }
1696}
1697
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1699 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301700 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001701 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001703 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301705 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1706 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301708 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301710 }
1711 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001713 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001715 return
1716 }
1717 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 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 +00001719 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001720 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001721 return
1722 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301724 log.Fields{"device-id": dh.deviceID})
1725 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001726 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001727
1728 // Initialize classical L2 PM Interval Counters
1729 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1730 // There is no way we should be landing here, but if we do then
1731 // there is nothing much we can do about this other than log error
1732 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1733 }
1734
mpagenkofc4f56e2020-11-04 17:17:49 +00001735 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301736 // *** should generate UniUnlockStateDone event *****
1737 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301739 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301740 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301742 }
1743}
1744
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1746 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301747
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001748 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301750 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1752 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001753 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001755 return
1756 }
1757 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 if err := dh.storePersistentData(ctx); err != nil {
1759 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001760 log.Fields{"device-id": dh.deviceID, "err": err})
1761 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301762 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 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 +05301764 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001766 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301767 }
1768}
1769
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1771 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001772 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001774 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1775 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001777 }
1778
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001780 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001782
1783 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001785
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001787 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789 return
1790 }
1791 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 if err := dh.storePersistentData(ctx); err != nil {
1793 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001794 log.Fields{"device-id": dh.deviceID, "err": err})
1795 }
mpagenko900ee4b2020-10-12 11:56:34 +00001796}
1797
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1799 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001800 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001802 voltha.OperStatus_ACTIVE); err != nil {
1803 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001805 }
1806
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001808 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001809 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001811
1812 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001814
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001816 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818 return
1819 }
1820 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 if err := dh.storePersistentData(ctx); err != nil {
1822 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001823 log.Fields{"device-id": dh.deviceID, "err": err})
1824 }
mpagenko900ee4b2020-10-12 11:56:34 +00001825}
1826
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001828 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001830 // attention: the device reason update is done based on ONU-UNI-Port related activity
1831 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001832 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001833 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001834 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301835 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001836 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001837 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001838 }
1839 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001841 // attention: the device reason update is done based on ONU-UNI-Port related activity
1842 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001843 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001844 // 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 +00001845 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001846 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001847 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301848}
1849
dbainbri4d3a0dc2020-12-02 00:33:42 +00001850func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1851 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001852 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301853 // attention: the device reason update is done based on ONU-UNI-Port related activity
1854 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301855
mpagenkofc4f56e2020-11-04 17:17:49 +00001856 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001857 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001858 // which may be the case from some previous actvity on another UNI Port of the ONU
1859 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001860 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1861 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001863 }
1864 }
1865 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001866 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001867 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001869 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301870 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001871 if err := dh.storePersistentData(ctx); err != nil {
1872 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1873 log.Fields{"device-id": dh.deviceID, "err": err})
1874 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301875}
1876
Himani Chawla6d2ae152020-09-02 13:11:20 +05301877//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301879 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001880 case MibDatabaseSync:
1881 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001883 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001884 case UniLockStateDone:
1885 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001887 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001888 case MibDownloadDone:
1889 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001891 }
1892 case UniUnlockStateDone:
1893 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001895 }
mpagenko900ee4b2020-10-12 11:56:34 +00001896 case UniEnableStateDone:
1897 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001899 }
1900 case UniDisableStateDone:
1901 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001903 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001904 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001905 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001907 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001908 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001909 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001911 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001912 default:
1913 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001915 }
1916 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001917}
1918
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001920 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301922 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001923 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001925 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301926 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001928 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001930 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001931 //store UniPort with the System-PortNumber key
1932 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001933 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001934 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1936 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001937 } //error logging already within UniPort method
1938 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001940 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001941 }
1942 }
1943}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001944
mpagenko3af1f032020-06-10 08:53:41 +00001945// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001947 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301948 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001949 // with following remark:
1950 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1951 // # load on the core
1952
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001953 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001954
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001955 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001956 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301957 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301959 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001960 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001961 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001963 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001964 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001966 }
mpagenko3af1f032020-06-10 08:53:41 +00001967 }
1968 }
1969}
1970
1971// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001973 // compare enableUniPortStateUpdate() above
1974 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1975 for uniNo, uniPort := range dh.uniEntityMap {
1976 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301977 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301979 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001980 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 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 +00001982 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001983 }
1984}
1985
1986// ONU_Active/Inactive announcement on system KAFKA bus
1987// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001989 var de voltha.DeviceEvent
1990 eventContext := make(map[string]string)
1991 //Populating event context
1992 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001994 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301996 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001997 }
1998 oltSerialNumber := parentDevice.SerialNumber
1999
2000 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2001 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2002 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302003 eventContext["olt-serial-number"] = oltSerialNumber
2004 eventContext["device-id"] = aDeviceID
2005 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002006 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002007 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002008
2009 /* Populating device event body */
2010 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302011 de.ResourceId = aDeviceID
2012 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002013 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2014 de.Description = fmt.Sprintf("%s Event - %s - %s",
2015 cEventObjectType, cOnuActivatedEvent, "Raised")
2016 } else {
2017 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2018 de.Description = fmt.Sprintf("%s Event - %s - %s",
2019 cEventObjectType, cOnuActivatedEvent, "Cleared")
2020 }
2021 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2023 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302024 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002025 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302027 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002028}
2029
Himani Chawla4d908332020-08-31 12:30:20 +05302030// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002032 chLSFsm := make(chan Message, 2048)
2033 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302034 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002036 sFsmName = "LockStateFSM"
2037 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002038 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002039 sFsmName = "UnLockStateFSM"
2040 }
mpagenko3af1f032020-06-10 08:53:41 +00002041
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002043 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002044 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002045 return
2046 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002048 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002049 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302050 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002051 dh.pLockStateFsm = pLSFsm
2052 } else {
2053 dh.pUnlockStateFsm = pLSFsm
2054 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002056 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002058 }
2059}
2060
2061// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002063 /* Uni Port lock/unlock procedure -
2064 ***** should run via 'adminDone' state and generate the argument requested event *****
2065 */
2066 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302067 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002068 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2069 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2070 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002071 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302072 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002073 }
2074 } else {
2075 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2076 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2077 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002078 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302079 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002080 }
2081 }
2082 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002083 if pLSStatemachine.Is(uniStDisabled) {
2084 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002085 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002086 // maybe try a FSM reset and then again ... - TODO!!!
2087 } else {
2088 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002090 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002091 }
2092 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002094 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002095 // maybe try a FSM reset and then again ... - TODO!!!
2096 }
2097 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002098 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002099 // maybe try a FSM reset and then again ... - TODO!!!
2100 }
2101}
2102
Himani Chawla6d2ae152020-09-02 13:11:20 +05302103//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002105
2106 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002107 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002108 kvbackend := &db.Backend{
2109 Client: dh.pOpenOnuAc.kvClient,
2110 StoreType: dh.pOpenOnuAc.KVStoreType,
2111 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002112 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002113 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2114 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002115
mpagenkoaf801632020-07-03 10:00:42 +00002116 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002117}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002118func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302119 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002120
mpagenkodff5dda2020-08-28 11:52:01 +00002121 for _, field := range flow.GetOfbFields(apFlowItem) {
2122 switch field.Type {
2123 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2124 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002126 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2127 }
mpagenko01e726e2020-10-23 09:45:29 +00002128 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002129 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2130 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302131 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002132 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302133 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2134 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002135 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2136 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002137 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2138 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302139 return
mpagenkodff5dda2020-08-28 11:52:01 +00002140 }
2141 }
mpagenko01e726e2020-10-23 09:45:29 +00002142 */
mpagenkodff5dda2020-08-28 11:52:01 +00002143 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2144 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302145 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002146 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302147 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002148 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302149 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002150 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302152 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002153 }
2154 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2155 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002158 "PCP": loAddPcp})
2159 }
2160 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2161 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002162 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002163 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2164 }
2165 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2166 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002168 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2169 }
2170 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2171 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002173 "IPv4-DST": field.GetIpv4Dst()})
2174 }
2175 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2176 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002178 "IPv4-SRC": field.GetIpv4Src()})
2179 }
2180 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2181 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002183 "Metadata": field.GetTableMetadata()})
2184 }
2185 /*
2186 default:
2187 {
2188 //all other entires ignored
2189 }
2190 */
2191 }
2192 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302193}
mpagenkodff5dda2020-08-28 11:52:01 +00002194
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002196 for _, action := range flow.GetActions(apFlowItem) {
2197 switch action.Type {
2198 /* not used:
2199 case of.OfpActionType_OFPAT_OUTPUT:
2200 {
mpagenko01e726e2020-10-23 09:45:29 +00002201 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002202 "Output": action.GetOutput()})
2203 }
2204 */
2205 case of.OfpActionType_OFPAT_PUSH_VLAN:
2206 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002208 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2209 }
2210 case of.OfpActionType_OFPAT_SET_FIELD:
2211 {
2212 pActionSetField := action.GetSetField()
2213 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002215 "OxcmClass": pActionSetField.Field.OxmClass})
2216 }
2217 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302218 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302220 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002221 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302222 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302224 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002225 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002227 "Type": pActionSetField.Field.GetOfbField().Type})
2228 }
2229 }
2230 /*
2231 default:
2232 {
2233 //all other entires ignored
2234 }
2235 */
2236 }
2237 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302238}
2239
2240//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302242 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2243 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2244 var loAddPcp, loSetPcp uint8
2245 var loIPProto uint32
2246 /* the TechProfileId is part of the flow Metadata - compare also comment within
2247 * OLT-Adapter:openolt_flowmgr.go
2248 * Metadata 8 bytes:
2249 * Most Significant 2 Bytes = Inner VLAN
2250 * Next 2 Bytes = Tech Profile ID(TPID)
2251 * Least Significant 4 Bytes = Port ID
2252 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2253 * subscriber related flows.
2254 */
2255
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302257 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302259 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002260 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302261 }
mpagenko551a4d42020-12-08 18:09:20 +00002262 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002263 loCookie := apFlowItem.GetCookie()
2264 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002266 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302267
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002269 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302270 if loIPProto == 2 {
2271 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2272 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002273 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2274 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302275 return nil
2276 }
mpagenko01e726e2020-10-23 09:45:29 +00002277 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002278 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002279
2280 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002281 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002282 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2283 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2284 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2285 //TODO!!: Use DeviceId within the error response to rwCore
2286 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002287 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002288 }
2289 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002291 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2292 } else {
2293 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2294 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2295 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302296 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002297 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002299 }
mpagenko9a304ea2020-12-16 15:54:01 +00002300
2301 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2302 dh.lockVlanConfig.Lock()
2303 defer dh.lockVlanConfig.Unlock()
2304 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302305 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002307 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002308 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002309 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002310 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002311}
2312
2313//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002314func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002315 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2316 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2317 //no extra check is done on the rule parameters
2318 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2319 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2320 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2321 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002322 // - 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 +00002323 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002325
2326 /* TT related temporary workaround - should not be needed anymore
2327 for _, field := range flow.GetOfbFields(apFlowItem) {
2328 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2329 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002330 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002331 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2332 if loIPProto == 2 {
2333 // 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 +00002334 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002335 log.Fields{"device-id": dh.deviceID})
2336 return nil
2337 }
2338 }
2339 } //for all OfbFields
2340 */
2341
mpagenko9a304ea2020-12-16 15:54:01 +00002342 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2343 dh.lockVlanConfig.Lock()
2344 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002345 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002346 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002347 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002349 log.Fields{"device-id": dh.deviceID})
2350 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002351 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002352 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002353
mpagenko01e726e2020-10-23 09:45:29 +00002354 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002355}
2356
Himani Chawla26e555c2020-08-31 12:30:20 +05302357// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002358// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002359func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002360 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002361 chVlanFilterFsm := make(chan Message, 2048)
2362
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002364 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002365 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302366 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002367 }
2368
dbainbri4d3a0dc2020-12-02 00:33:42 +00002369 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002370 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2371 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002372 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302373 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002374 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2375 if pVlanFilterStatemachine != nil {
2376 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2377 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002380 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302381 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302383 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2384 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002385 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002387 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302388 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002389 }
2390 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002392 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302393 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002394 }
2395 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002396 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002397 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302398 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002399 }
2400 return nil
2401}
2402
mpagenkofc4f56e2020-11-04 17:17:49 +00002403//VerifyVlanConfigRequest checks on existence of a given uniPort
2404// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002405func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002406 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2407 var pCurrentUniPort *onuUniPort
2408 for _, uniPort := range dh.uniEntityMap {
2409 // only if this port is validated for operState transfer
2410 if uniPort.uniID == uint8(aUniID) {
2411 pCurrentUniPort = uniPort
2412 break //found - end search loop
2413 }
2414 }
2415 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002417 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2418 return
2419 }
mpagenko551a4d42020-12-08 18:09:20 +00002420 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002421}
2422
mpagenkodff5dda2020-08-28 11:52:01 +00002423//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002424func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002425 //TODO!! verify and start pending flow configuration
2426 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2427 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302428 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002429 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2430 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2431 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002432 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2433 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2434 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2435 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2436 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2437 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2438 } else {
2439 /***** UniVlanConfigFsm continued */
2440 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2441 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2442 "UniPort": apUniPort.portNo})
2443 }
2444 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2445 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2446 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2447 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2448 } else {
2449 /***** UniVlanConfigFsm continued */
2450 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2451 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2452 "UniPort": apUniPort.portNo})
2453 }
mpagenkodff5dda2020-08-28 11:52:01 +00002454 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002455 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2456 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002457 "UniPort": apUniPort.portNo})
2458 }
2459 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002460 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2461 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2462 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002463 }
2464 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002466 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002467 }
mpagenkodff5dda2020-08-28 11:52:01 +00002468 } // else: nothing to do
2469}
2470
2471//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2472// 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 +00002473func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2474 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002475 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2476 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302477 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002478}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002479
Girish Gowdra26a40922021-01-29 17:14:34 -08002480//ProcessPendingTpDelete processes any pending TP delete (if available)
2481func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2482 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2483 if apUniPort == nil {
2484 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2485 return
2486 }
2487 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2488 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2489 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2490 if pAniConfigStatemachine != nil {
2491 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2492 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2493 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2494 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2495 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2496 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2497 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2498 return
2499 }
2500 } else {
2501 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2502 return
2503 }
2504 }
2505 return
2506 }
2507}
2508
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002509//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2510//available for potential reconcilement
2511
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002513
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002514 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002515 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002516 return nil
2517 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002518 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002519
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002521 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002523 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2524 }
2525 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2526
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002527 // deadline context to ensure completion of background routines waited for
2528 //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 +05302529 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002530 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2531
2532 pDevEntry.resetKvProcessingErrorIndication()
2533 var wg sync.WaitGroup
2534 wg.Add(1) // for the 1 go routine to finish
2535
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2537 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002538
2539 return pDevEntry.getKvProcessingErrorIndication()
2540}
2541
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002543 defer cancel() //ensure termination of context (may be pro forma)
2544 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002546 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002547}
2548
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002550
2551 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002552 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002553 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002554 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2555 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002556 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002557 return err
2558 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002560 return nil
2561 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002562 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002563 return nil
2564}
2565
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2567 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002568 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002570 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2571 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002572 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2573 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2574
2575 pDevEntry.resetKvProcessingErrorIndication()
2576 var wg sync.WaitGroup
2577 wg.Add(1) // for the 1 go routine to finish
2578
2579 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002580 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002581
2582 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002583 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002584 return err
2585 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002586 return nil
2587}
2588
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002589func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2590 var errStr string = ""
2591 for _, err := range errS {
2592 if err != nil {
2593 errStr = errStr + err.Error() + " "
2594 }
2595 }
2596 if errStr != "" {
2597 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2598 }
2599 return nil
2600}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002601
2602// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2603func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2604 dh.lockDevice.RLock()
2605 defer dh.lockDevice.RUnlock()
2606 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2607 return uniPort.entityID, nil
2608 }
2609 return 0, errors.New("error-fetching-uni-port")
2610}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002611
2612// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002613func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2614 var errorsList []error
2615 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 -08002616
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002617 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2618 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2619 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2620
2621 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2622 // successfully.
2623 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2624 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2625 if len(errorsList) > 0 {
2626 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2627 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002628 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002629 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2630 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002631}
2632
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002633func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2634 var err error
2635 var errorsList []error
2636 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2637
2638 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2639 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2640 errorsList = append(errorsList, err)
2641 }
2642 }
2643
2644 return errorsList
2645}
2646
2647func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2648 var err error
2649 var errorsList []error
2650 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2651 // Check if group metric related config is updated
2652 for _, v := range pmConfigs.Groups {
2653 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2654 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2655 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2656
2657 if ok && m.frequency != v.GroupFreq {
2658 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2659 errorsList = append(errorsList, err)
2660 }
2661 }
2662 if ok && m.enabled != v.Enabled {
2663 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2664 errorsList = append(errorsList, err)
2665 }
2666 }
2667 }
2668 return errorsList
2669}
2670
2671func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2672 var err error
2673 var errorsList []error
2674 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2675 // Check if standalone metric related config is updated
2676 for _, v := range pmConfigs.Metrics {
2677 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002678 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002679 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2680
2681 if ok && m.frequency != v.SampleFreq {
2682 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2683 errorsList = append(errorsList, err)
2684 }
2685 }
2686 if ok && m.enabled != v.Enabled {
2687 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2688 errorsList = append(errorsList, err)
2689 }
2690 }
2691 }
2692 return errorsList
2693}
2694
2695// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002696func (dh *deviceHandler) startCollector(ctx context.Context) {
2697 logger.Debugf(ctx, "startingCollector")
2698
2699 // Start routine to process OMCI GET Responses
2700 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002701 // Initialize the next metric collection time.
2702 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2703 // reset like onu rebooted.
2704 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002705 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002706 for {
2707 select {
2708 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002709 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002710 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002711 // Stop the L2 PM FSM
2712 go func() {
2713 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2714 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2715 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2716 }
2717 } else {
2718 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2719 }
2720 }()
2721
Girish Gowdrae09a6202021-01-12 18:10:59 -08002722 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002723 dh.pOnuMetricsMgr.stopTicks <- true
2724
Girish Gowdrae09a6202021-01-12 18:10:59 -08002725 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002726 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2727 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2728 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2729 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2730 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002731 // Update the next metric collection time.
2732 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002733 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002734 } else {
2735 if dh.pmConfigs.Grouped { // metrics are managed as a group
2736 // parse through the group and standalone metrics to see it is time to collect their metrics
2737 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002738
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002739 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2740 // 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 -08002741 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2742 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002743 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2744 }
2745 }
2746 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2747 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2748 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2749 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2750 }
2751 }
2752 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2753
2754 // parse through the group and update the next metric collection time
2755 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2756 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2757 // 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 -08002758 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2759 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002760 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2761 }
2762 }
2763 // parse through the standalone metrics and update the next metric collection time
2764 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2765 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2766 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2767 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2768 }
2769 }
2770 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2771 } /* else { // metrics are not managed as a group
2772 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2773 } */
2774 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002775 }
2776 }
2777}
kesavandfdf77632021-01-26 23:40:33 -05002778
2779func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2780
2781 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2782 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2783}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002784
2785func (dh *deviceHandler) isFsmInState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2786 var currentState string
2787 if pFsm != nil {
2788 currentState = pFsm.Current()
2789 if currentState == wantedState {
2790 return true
2791 }
2792 } else {
2793 logger.Warnw(ctx, "FSM not defined!", log.Fields{"wantedState": wantedState, "device-id": dh.deviceID})
2794 }
2795 return false
2796}
2797
2798func (dh *deviceHandler) mibUploadFsmInIdleState(ctx context.Context, idleState string) bool {
2799 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibUploadFsm.pFsm, idleState)
2800}
2801
2802func (dh *deviceHandler) mibDownloadFsmInIdleState(ctx context.Context, idleState string) bool {
2803 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibDownloadFsm.pFsm, idleState)
2804}
2805
2806func (dh *deviceHandler) devUniLockFsmInIdleState(ctx context.Context, idleState string) bool {
2807 return dh.isFsmInState(ctx, dh.pLockStateFsm.pAdaptFsm.pFsm, idleState)
2808}
2809
2810func (dh *deviceHandler) devUniUnlockFsmInIdleState(ctx context.Context, idleState string) bool {
2811 return dh.isFsmInState(ctx, dh.pUnlockStateFsm.pAdaptFsm.pFsm, idleState)
2812}
2813
2814func (dh *deviceHandler) devAniConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2815 if dh.pOnuTP.pAniConfigFsm != nil {
2816 for _, v := range dh.pOnuTP.pAniConfigFsm {
2817 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2818 return false
2819 }
2820 }
2821 return true
2822 }
2823 logger.Warnw(ctx, "AniConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2824 return false
2825}
2826
2827func (dh *deviceHandler) devUniVlanConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2828 if dh.UniVlanConfigFsmMap != nil {
2829 for _, v := range dh.UniVlanConfigFsmMap {
2830 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2831 return false
2832 }
2833 }
2834 return true
2835 }
2836 logger.Warnw(ctx, "UniVlanConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2837 return false
2838}
2839
Girish Gowdrae0140f02021-02-02 16:55:09 -08002840func (dh *deviceHandler) l2PmFsmInIdleState(ctx context.Context, idleState string) bool {
2841 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2842 return dh.isFsmInState(ctx, dh.pOnuMetricsMgr.pAdaptFsm.pFsm, idleState)
2843 }
2844 logger.Warnw(ctx, "L2 PM FSM not defined!", log.Fields{"device-id": dh.deviceID})
2845 return false
2846}
2847
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002848func (dh *deviceHandler) allButCallingFsmInIdleState(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
2849 for fsmName, fsmStruct := range fsmIdleStateFuncMap {
2850 if fsmName != callingFsm && !fsmStruct.idleCheckFunc(dh, ctx, fsmStruct.idleState) {
2851 return false
2852 }
2853 }
2854 return true
2855}
2856
2857func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
2858 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
2859 if err := dh.resetFsms(ctx, false); err != nil {
2860 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
2861 // TODO: fatal error reset ONU, delete deviceHandler!
2862 return
2863 }
2864 if !dh.getCollectorIsRunning() {
2865 // Start PM collector routine
2866 go dh.startCollector(ctx)
2867 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302868 if !dh.getAlarmManagerIsRunning() {
2869 go dh.startAlarmManager(ctx)
2870 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002871 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002872 dh.startReconciling(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002873}
2874
2875func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
2876 dh.mutexCollectorFlag.Lock()
2877 dh.collectorIsRunning = flagValue
2878 dh.mutexCollectorFlag.Unlock()
2879}
2880
2881func (dh *deviceHandler) getCollectorIsRunning() bool {
2882 dh.mutexCollectorFlag.RLock()
2883 flagValue := dh.collectorIsRunning
2884 dh.mutexCollectorFlag.RUnlock()
2885 return flagValue
2886}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302887
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302888func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
2889 dh.mutextAlarmManagerFlag.Lock()
2890 dh.alarmManagerIsRunning = flagValue
2891 dh.mutextAlarmManagerFlag.Unlock()
2892}
2893
2894func (dh *deviceHandler) getAlarmManagerIsRunning() bool {
2895 dh.mutextAlarmManagerFlag.RLock()
2896 flagValue := dh.alarmManagerIsRunning
2897 dh.mutextAlarmManagerFlag.RUnlock()
2898 return flagValue
2899}
2900
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302901func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
2902 logger.Debugf(ctx, "startingAlarmManager")
2903
2904 // Start routine to process OMCI GET Responses
2905 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302906 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302907 if stop := <-dh.stopAlarmManager; stop {
2908 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2909 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302910 dh.setAlarmManagerIsRunning(false)
2911
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302912 }
2913}
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002914func (dh *deviceHandler) startReconciling(ctx context.Context) {
2915 logger.Debugw(ctx, "start reconciling", log.Fields{"device-id": dh.deviceID})
2916 if !dh.isReconciling() {
2917 go func() {
2918 select {
2919 case <-dh.chReconcilingFinished:
2920 logger.Debugw(ctx, "reconciling has been finished in time",
2921 log.Fields{"device-id": dh.deviceID})
2922 case <-time.After(time.Duration(cReconcilingTimeout) * time.Second):
2923 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
2924 log.Fields{"device-id": dh.deviceID})
2925 }
2926 dh.mutexReconcilingFlag.Lock()
2927 dh.reconciling = false
2928 dh.mutexReconcilingFlag.Unlock()
2929 }()
2930 dh.mutexReconcilingFlag.Lock()
2931 dh.reconciling = true
2932 dh.mutexReconcilingFlag.Unlock()
2933 } else {
2934 logger.Warnw(ctx, "reconciling is already running", log.Fields{"device-id": dh.deviceID})
2935 }
2936}
2937
2938func (dh *deviceHandler) stopReconciling(ctx context.Context) {
2939 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
2940 if dh.isReconciling() {
2941 dh.chReconcilingFinished <- true
2942 } else {
2943 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
2944 }
2945}
2946
2947func (dh *deviceHandler) isReconciling() bool {
2948 dh.mutexReconcilingFlag.RLock()
2949 value := dh.reconciling
2950 dh.mutexReconcilingFlag.RUnlock()
2951 return value
2952}