blob: c55afd38d9f2910460efa9e3c292f8462560e73b [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/hex"
23 "errors"
24 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
34 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053035 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000036 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v4/pkg/log"
38 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050039 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000040 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
41 "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v4/go/openolt"
45 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000046)
47
48/*
49// Constants for number of retries and for timeout
50const (
51 MaxRetry = 10
52 MaxTimeOutInMs = 500
53)
54*/
55
mpagenko1cc3cb42020-07-27 15:24:38 +000056const (
57 // events of Device FSM
58 devEvDeviceInit = "devEvDeviceInit"
59 devEvGrpcConnected = "devEvGrpcConnected"
60 devEvGrpcDisconnected = "devEvGrpcDisconnected"
61 devEvDeviceUpInd = "devEvDeviceUpInd"
62 devEvDeviceDownInd = "devEvDeviceDownInd"
63)
64const (
65 // states of Device FSM
66 devStNull = "devStNull"
67 devStDown = "devStDown"
68 devStInit = "devStInit"
69 devStConnected = "devStConnected"
70 devStUp = "devStUp"
71)
72
Holger Hildebrandt24d51952020-05-04 14:03:42 +000073//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
74const (
Himani Chawla4d908332020-08-31 12:30:20 +053075 pon = voltha.EventSubCategory_PON
76 //olt = voltha.EventSubCategory_OLT
77 //ont = voltha.EventSubCategory_ONT
78 //onu = voltha.EventSubCategory_ONU
79 //nni = voltha.EventSubCategory_NNI
80 //service = voltha.EventCategory_SERVICE
81 //security = voltha.EventCategory_SECURITY
82 equipment = voltha.EventCategory_EQUIPMENT
83 //processing = voltha.EventCategory_PROCESSING
84 //environment = voltha.EventCategory_ENVIRONMENT
85 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000086)
87
88const (
89 cEventObjectType = "ONU"
90)
91const (
92 cOnuActivatedEvent = "ONU_ACTIVATED"
93)
94
Holger Hildebrandt10d98192021-01-27 15:29:31 +000095type usedOmciConfigFsms int
96
97const (
98 cUploadFsm usedOmciConfigFsms = iota
99 cDownloadFsm
100 cUniLockFsm
101 cUniUnLockFsm
102 cAniConfigFsm
103 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800104 cL2PmFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
mpagenkof1fc3862021-02-16 10:09:52 +0000107type omciIdleCheckStruct struct {
108 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
109 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110}
111
mpagenkof1fc3862021-02-16 10:09:52 +0000112var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
113 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
119 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000122const (
123 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000124 drUnset = 0
125 drActivatingOnu = 1
126 drStartingOpenomci = 2
127 drDiscoveryMibsyncComplete = 3
128 drInitialMibDownloaded = 4
129 drTechProfileConfigDownloadSuccess = 5
130 drOmciFlowsPushed = 6
131 drOmciAdminLock = 7
132 drOnuReenabled = 8
133 drStoppingOpenomci = 9
134 drRebooting = 10
135 drOmciFlowsDeleted = 11
136 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000137)
138
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000139var deviceReasonMap = map[uint8]string{
140 drUnset: "unset",
141 drActivatingOnu: "activating-onu",
142 drStartingOpenomci: "starting-openomci",
143 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
144 drInitialMibDownloaded: "initial-mib-downloaded",
145 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
146 drOmciFlowsPushed: "omci-flows-pushed",
147 drOmciAdminLock: "omci-admin-lock",
148 drOnuReenabled: "onu-reenabled",
149 drStoppingOpenomci: "stopping-openomci",
150 drRebooting: "rebooting",
151 drOmciFlowsDeleted: "omci-flows-deleted",
152 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
153}
154
Himani Chawla6d2ae152020-09-02 13:11:20 +0530155//deviceHandler will interact with the ONU ? device.
156type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000157 deviceID string
158 DeviceType string
159 adminState string
160 device *voltha.Device
161 logicalDeviceID string
162 ProxyAddressID string
163 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530164 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000165 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000166
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000167 coreProxy adapterif.CoreProxy
168 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530169 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000170
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800171 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800172
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173 pOpenOnuAc *OpenONUAC
174 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530175 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000176 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000177 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530178 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800179 pOnuMetricsMgr *onuMetricsManager
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530180 pAlarmMgr *onuAlarmManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000181 exitChannel chan int
182 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000183 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000184 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530185 pLockStateFsm *lockStateFsm
186 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000188 //flowMgr *OpenOltFlowMgr
189 //eventMgr *OpenOltEventMgr
190 //resourceMgr *rsrcMgr.OpenOltResourceMgr
191
192 //discOnus sync.Map
193 //onus sync.Map
194 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000195 collectorIsRunning bool
196 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000197 stopCollector chan bool
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530198 alarmManagerIsRunning bool
199 mutextAlarmManagerFlag sync.RWMutex
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530200 stopAlarmManager chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000201 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000202 uniEntityMap map[uint32]*onuUniPort
mpagenkof1fc3862021-02-16 10:09:52 +0000203 mutexKvStoreContext sync.Mutex
204 lockVlanConfig sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000205 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
206 reconciling bool
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000207 mutexReconcilingFlag sync.RWMutex
208 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
mpagenkofc4f56e2020-11-04 17:17:49 +0000209 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210}
211
Himani Chawla6d2ae152020-09-02 13:11:20 +0530212//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530213func 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 +0530214 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 dh.coreProxy = cp
216 dh.AdapterProxy = ap
217 dh.EventProxy = ep
218 cloned := (proto.Clone(device)).(*voltha.Device)
219 dh.deviceID = cloned.Id
220 dh.DeviceType = cloned.Type
221 dh.adminState = "up"
222 dh.device = cloned
223 dh.pOpenOnuAc = adapter
224 dh.exitChannel = make(chan int, 1)
225 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000226 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000227 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530229 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530230 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000231 dh.stopHeartbeatCheck = make(chan bool, 2)
232 //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 +0000233 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530234 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000235 dh.lockVlanConfig = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000236 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000237 dh.reconciling = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000238 dh.chReconcilingFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000239 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800241 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
242 dh.pmConfigs = cloned.PmConfigs
243 } /* else {
244 // will be populated when onu_metrics_mananger is initialized.
245 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800246
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 // Device related state machine
248 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000249 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000251 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
252 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
253 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
254 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
255 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 },
257 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000258 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
259 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
260 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
261 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
262 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
263 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
264 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
265 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000266 },
267 )
mpagenkoaf801632020-07-03 10:00:42 +0000268
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269 return &dh
270}
271
Himani Chawla6d2ae152020-09-02 13:11:20 +0530272// start save the device to the data model
273func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000274 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000275 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000276 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277}
278
Himani Chawla4d908332020-08-31 12:30:20 +0530279/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530281func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000282 logger.Debug("stopping-device-handler")
283 dh.exitChannel <- 1
284}
Himani Chawla4d908332020-08-31 12:30:20 +0530285*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286
287// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530288// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289
Girish Gowdrae0140f02021-02-02 16:55:09 -0800290//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530291func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000292 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000295 if dh.pDeviceStateFsm.Is(devStNull) {
296 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800300 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
301 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800302 // Now, set the initial PM configuration for that device
303 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
304 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
305 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800306 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 }
310
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311}
312
mpagenko057889c2021-01-21 16:51:58 +0000313func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530314 msgBody := msg.GetBody()
315 omciMsg := &ic.InterAdapterOmciMessage{}
316 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000317 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530318 "device-id": dh.deviceID, "error": err})
319 return err
320 }
321
322 //assuming omci message content is hex coded!
323 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000324 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530325 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000328 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000330 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 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 +0530332 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000334 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530335}
336
Himani Chawla6d2ae152020-09-02 13:11:20 +0530337func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000338 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530339 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000340
dbainbri4d3a0dc2020-12-02 00:33:42 +0000341 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000342
dbainbri4d3a0dc2020-12-02 00:33:42 +0000343 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000344 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000346 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
347 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 if dh.pOnuTP == nil {
349 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000352 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000354 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000356 "device-state": deviceReasonMap[dh.deviceReason]})
357 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000359 //previous state test here was just this one, now extended for more states to reject the SetRequest:
360 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
361 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530362
363 msgBody := msg.GetBody()
364 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
365 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 "device-id": dh.deviceID, "error": err})
368 return err
369 }
370
371 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
373 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376
377 if techProfMsg.UniId > 255 {
378 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
379 techProfMsg.UniId, dh.deviceID))
380 }
381 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800382 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
383 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800385 return err
386 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000387
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 // if there has been some change for some uni TechProfilePath
390 //in order to allow concurrent calls to other dh instances we do not wait for execution here
391 //but doing so we can not indicate problems to the caller (who does what with that then?)
392 //by now we just assume straightforward successful execution
393 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
394 // possible problems to the caller later autonomously
395
396 // deadline context to ensure completion of background routines waited for
397 //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 +0530398 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 dctx, cancel := context.WithDeadline(context.Background(), deadline)
400
Girish Gowdra041dcb32020-11-16 16:54:30 -0800401 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 pDevEntry.resetKvProcessingErrorIndication()
403
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 var wg sync.WaitGroup
405 wg.Add(2) // for the 2 go routines to finish
406 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
408 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
409 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410
Girish Gowdra041dcb32020-11-16 16:54:30 -0800411 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530414 return nil
415}
416
Himani Chawla6d2ae152020-09-02 13:11:20 +0530417func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 msg *ic.InterAdapterMessage) error {
420
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000422
dbainbri4d3a0dc2020-12-02 00:33:42 +0000423 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000425 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
427 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530428 if dh.pOnuTP == nil {
429 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000430 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530433 }
434
435 msgBody := msg.GetBody()
436 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
437 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000438 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530439 "device-id": dh.deviceID, "error": err})
440 return err
441 }
442
443 //compare TECH_PROFILE_DOWNLOAD_REQUEST
444 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530446
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447 if delGemPortMsg.UniId > 255 {
448 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
449 delGemPortMsg.UniId, dh.deviceID))
450 }
451 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800452 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
453 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000454 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 -0800455 return err
456 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530457
mpagenkofc4f56e2020-11-04 17:17:49 +0000458 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459
mpagenkofc4f56e2020-11-04 17:17:49 +0000460 // deadline context to ensure completion of background routines waited for
461 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
462 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000463
Girish Gowdra041dcb32020-11-16 16:54:30 -0800464 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000465
mpagenkofc4f56e2020-11-04 17:17:49 +0000466 var wg sync.WaitGroup
467 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000468 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000469 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000471
Girish Gowdra041dcb32020-11-16 16:54:30 -0800472 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530473}
474
Himani Chawla6d2ae152020-09-02 13:11:20 +0530475func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000480
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
485 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 if dh.pOnuTP == nil {
487 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000488 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 }
492
493 msgBody := msg.GetBody()
494 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
495 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530497 "device-id": dh.deviceID, "error": err})
498 return err
499 }
500
501 //compare TECH_PROFILE_DOWNLOAD_REQUEST
502 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000504
505 if delTcontMsg.UniId > 255 {
506 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
507 delTcontMsg.UniId, dh.deviceID))
508 }
509 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 tpPath := delTcontMsg.TpPath
511 tpID, err := GetTpIDFromTpPath(tpPath)
512 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800514 return err
515 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
dbainbri4d3a0dc2020-12-02 00:33:42 +0000517 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530518 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530519 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530520 dctx, cancel := context.WithDeadline(context.Background(), deadline)
521
Girish Gowdra041dcb32020-11-16 16:54:30 -0800522 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 pDevEntry.resetKvProcessingErrorIndication()
524
Himani Chawla26e555c2020-08-31 12:30:20 +0530525 var wg sync.WaitGroup
526 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530528 cResourceTcont, delTcontMsg.AllocId, &wg)
529 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
531 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532
Girish Gowdra041dcb32020-11-16 16:54:30 -0800533 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 return nil
536}
537
Himani Chawla6d2ae152020-09-02 13:11:20 +0530538//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000539// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
540// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000541func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000542 msgID := msg.Header.Id
543 msgType := msg.Header.Type
544 fromTopic := msg.Header.FromTopic
545 toTopic := msg.Header.ToTopic
546 toDeviceID := msg.Header.ToDeviceId
547 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000549 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
550
551 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000552 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000553 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
554 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000555 {
mpagenko057889c2021-01-21 16:51:58 +0000556 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000557 }
mpagenkoaf801632020-07-03 10:00:42 +0000558 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
559 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000560 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000561 }
562 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
563 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000565
mpagenkoaf801632020-07-03 10:00:42 +0000566 }
567 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
568 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000570 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 default:
572 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000573 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000574 "msgType": msg.Header.Type, "device-id": dh.deviceID})
575 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000576 }
577 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000578}
579
mpagenkodff5dda2020-08-28 11:52:01 +0000580//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
582 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000583 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000584 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000585
mpagenko01e726e2020-10-23 09:45:29 +0000586 var retError error = nil
587 //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 +0000588 if apOfFlowChanges.ToRemove != nil {
589 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000590 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000591 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000592 "device-id": dh.deviceID})
593 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000594 continue
595 }
596 flowInPort := flow.GetInPort(flowItem)
597 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000598 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 +0000599 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
600 continue
601 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000602 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000603 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000605 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000606 continue
607 } else {
608 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530609 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000610 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
611 loUniPort = uniPort
612 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000614 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
615 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
616 flowInPort, dh.deviceID)
617 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000618 }
619 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000621 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000622 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000624 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000625 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000627 log.Fields{"device-id": dh.deviceID, "error": err})
628 retError = err
629 continue
630 //return err
631 } else { // if last setting succeeds, overwrite possibly previously set error
632 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000633 }
634 }
635 }
636 }
mpagenko01e726e2020-10-23 09:45:29 +0000637 if apOfFlowChanges.ToAdd != nil {
638 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
639 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000640 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000641 "device-id": dh.deviceID})
642 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
643 continue
644 }
645 flowInPort := flow.GetInPort(flowItem)
646 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 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 +0000648 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
649 continue
650 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
651 } else if flowInPort == dh.ponPortNumber {
652 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000654 "device-id": dh.deviceID, "inPort": flowInPort})
655 continue
656 } else {
657 // this is the relevant upstream flow
658 var loUniPort *onuUniPort
659 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
660 loUniPort = uniPort
661 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000663 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
664 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
665 flowInPort, dh.deviceID)
666 continue
667 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
668 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000669 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
670 // if not, we just throw some error here to have an indication about that, if we really need to support that
671 // then we would need to create some means to activate the internal stored flows
672 // after the device gets active automatically (and still with its dependency to the TechProfile)
673 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
674 // also abort for the other still possible flows here
675 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000677 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000678 return fmt.Errorf("improper device state on device %s", dh.deviceID)
679 }
680
mpagenko01e726e2020-10-23 09:45:29 +0000681 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000683 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
684 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000686 //try next flow after processing error
687 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000689 log.Fields{"device-id": dh.deviceID, "error": err})
690 retError = err
691 continue
692 //return err
693 } else { // if last setting succeeds, overwrite possibly previously set error
694 retError = nil
695 }
696 }
697 }
698 }
699 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000700}
701
Himani Chawla6d2ae152020-09-02 13:11:20 +0530702//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000703//following are the expected device states after this activity:
704//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
705// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
707 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000708
mpagenko900ee4b2020-10-12 11:56:34 +0000709 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000710 //note that disableDevice sequences in some 'ONU active' state may yield also
711 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000712 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000713 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000714 //disable-device shall be just a UNi/ONU-G related admin state setting
715 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000716
mpagenkofc4f56e2020-11-04 17:17:49 +0000717 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000718 // disable UNI ports/ONU
719 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
720 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000722 } else { //LockStateFSM already init
723 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000725 }
726 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000728 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000730 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
731 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000733 }
mpagenko01e726e2020-10-23 09:45:29 +0000734 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000735
736 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000738 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300739 }
740}
741
Himani Chawla6d2ae152020-09-02 13:11:20 +0530742//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
744 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000745
mpagenkofc4f56e2020-11-04 17:17:49 +0000746 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
747 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
748 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
749 // for real ONU's that should have nearly no influence
750 // Note that for real ONU's there is anyway a problematic situation with following sequence:
751 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
752 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
753 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
754 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
755
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000756 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000757 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000758 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000760 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000761 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000763 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300764}
765
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
767 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000768
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000770 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000772 return
773 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000775 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000777 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000779 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000780 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000781 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000782 }
Himani Chawla4d908332020-08-31 12:30:20 +0530783 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000784 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
785 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
786 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
787 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000789}
790
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
792 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000793
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000795 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000797 return
798 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000799 dh.pOnuTP.lockTpProcMutex()
800 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000801 pDevEntry.persUniConfigMutex.RLock()
802 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000804 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000806 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000807 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000808 return
809 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000810 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000811 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
812 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000814 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000815 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000816 return
817 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800818 for tpID := range uniData.PersTpPathMap {
819 // deadline context to ensure completion of background routines waited for
820 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
821 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000823
Girish Gowdra041dcb32020-11-16 16:54:30 -0800824 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
825 var wg sync.WaitGroup
826 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
828 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800829 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800831 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000833 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000836 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000837 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 }
839}
840
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
842 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000845 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000847 return
848 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000849 pDevEntry.persUniConfigMutex.RLock()
850 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000851 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000853 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000854 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000855 return
856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000858 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
859 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000861 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000862 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000863 return
864 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000865 var uniPort *onuUniPort
866 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000868 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000869 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870 return
871 }
872 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000874 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000875 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000878 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
879 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000881 }
mpagenkof1fc3862021-02-16 10:09:52 +0000882 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000883 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000884 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000886 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000887 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000889 }
890 }
891 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000892 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000893 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000894 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000895 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000896 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000897 }
898}
899
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
901 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 +0000902
903 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000904 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000905}
906
dbainbri4d3a0dc2020-12-02 00:33:42 +0000907func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
908 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000911 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000912 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000913 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000914 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000915 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000916
917 // deadline context to ensure completion of background routines waited for
918 //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 +0530919 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000920 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000921
922 pDevEntry.resetKvProcessingErrorIndication()
923
924 var wg sync.WaitGroup
925 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
927 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000928
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000929 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000930 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000931}
932
dbainbri4d3a0dc2020-12-02 00:33:42 +0000933func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
934 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300935 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000936 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000937 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300938 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530940 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000941 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530942 return err
943 }
mpagenko01e726e2020-10-23 09:45:29 +0000944
945 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000947
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000949 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300951 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000952 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000953 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300954 return err
955 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300957 return err
958 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000959 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000960 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
961 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
962 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
963 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300964 return nil
965}
966
mpagenkoc8bba412021-01-15 15:38:44 +0000967//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
968func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
969 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
970 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000971 //return success to comfort the core processing during integration
972 return nil
mpagenkoc8bba412021-01-15 15:38:44 +0000973}
974
Himani Chawla6d2ae152020-09-02 13:11:20 +0530975// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000976// #####################################################################################
977
978// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530979// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000980
dbainbri4d3a0dc2020-12-02 00:33:42 +0000981func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
982 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 +0000983}
984
985// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000987
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000989 var err error
990
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000991 // populate what we know. rest comes later after mib sync
992 dh.device.Root = false
993 dh.device.Vendor = "OpenONU"
994 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000995 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000996 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000998 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000999
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001000 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1002 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301003 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001004 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001006 log.Fields{"device-id": dh.deviceID})
1007 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001008
Himani Chawla4d908332020-08-31 12:30:20 +05301009 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001010 dh.ponPortNumber = dh.device.ParentPortNo
1011
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001012 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1013 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1014 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001016 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301017 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001018
1019 /*
1020 self._pon = PonPort.create(self, self._pon_port_number)
1021 self._pon.add_peer(self.parent_id, self._pon_port_number)
1022 self.logger.debug('adding-pon-port-to-agent',
1023 type=self._pon.get_port().type,
1024 admin_state=self._pon.get_port().admin_state,
1025 oper_status=self._pon.get_port().oper_status,
1026 )
1027 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001028 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001029 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001030 var ponPortNo uint32 = 1
1031 if dh.ponPortNumber != 0 {
1032 ponPortNo = dh.ponPortNumber
1033 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001034
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001035 pPonPort := &voltha.Port{
1036 PortNo: ponPortNo,
1037 Label: fmt.Sprintf("pon-%d", ponPortNo),
1038 Type: voltha.Port_PON_ONU,
1039 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301040 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001041 PortNo: ponPortNo}}, // Peer port is parent's port number
1042 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1044 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001045 e.Cancel(err)
1046 return
1047 }
1048 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001052}
1053
1054// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001056
dbainbri4d3a0dc2020-12-02 00:33:42 +00001057 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001058 var err error
1059 /*
1060 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1061 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1062 return nil
1063 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1065 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001066 e.Cancel(err)
1067 return
1068 }
1069
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001070 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001071 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001072 // reconcilement will be continued after mib download is done
1073 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001074
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001075 /*
1076 ############################################################################
1077 # Setup Alarm handler
1078 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1079 device.serial_number)
1080 ############################################################################
1081 # Setup PM configuration for this device
1082 # Pass in ONU specific options
1083 kwargs = {
1084 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1085 'heartbeat': self.heartbeat,
1086 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1087 }
1088 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1089 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1090 self.logical_device_id, device.serial_number,
1091 grouped=True, freq_override=False, **kwargs)
1092 pm_config = self._pm_metrics.make_proto()
1093 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1094 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1095 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1096
1097 # Note, ONU ID and UNI intf set in add_uni_port method
1098 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1099 ani_ports=[self._pon])
1100
1101 # Code to Run OMCI Test Action
1102 kwargs_omci_test_action = {
1103 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1104 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1105 }
1106 serial_number = device.serial_number
1107 self._test_request = OmciTestRequest(self.core_proxy,
1108 self.omci_agent, self.device_id,
1109 AniG, serial_number,
1110 self.logical_device_id,
1111 exclusive=False,
1112 **kwargs_omci_test_action)
1113
1114 self.enabled = True
1115 else:
1116 self.logger.info('onu-already-activated')
1117 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001118
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001120}
1121
1122// doStateConnected get the device info and update to voltha core
1123// for comparison of the original method (not that easy to uncomment): compare here:
1124// voltha-openolt-adapter/adaptercore/device_handler.go
1125// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001127
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301129 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132}
1133
1134// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001136
dbainbri4d3a0dc2020-12-02 00:33:42 +00001137 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301138 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001139 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001141
1142 /*
1143 // Synchronous call to update device state - this method is run in its own go routine
1144 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1145 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001146 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 +00001147 return err
1148 }
1149 return nil
1150 */
1151}
1152
1153// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001157 var err error
1158
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001159 device := dh.device
1160 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001161 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001163 e.Cancel(err)
1164 return
1165 }
1166
1167 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001169 /*
1170 // Update the all ports state on that device to disable
1171 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001172 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001173 return er
1174 }
1175
1176 //Update the device oper state and connection status
1177 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1178 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1179 dh.device = cloned
1180
1181 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001182 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183 return er
1184 }
1185
1186 //get the child device for the parent device
1187 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1188 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001189 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001190 return err
1191 }
1192 for _, onuDevice := range onuDevices.Items {
1193
1194 // Update onu state as down in onu adapter
1195 onuInd := oop.OnuIndication{}
1196 onuInd.OperState = "down"
1197 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1198 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1199 if er != nil {
1200 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001201 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001202 //Do not return here and continue to process other ONUs
1203 }
1204 }
1205 // * Discovered ONUs entries need to be cleared , since after OLT
1206 // is up, it starts sending discovery indications again* /
1207 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001208 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001209 return nil
1210 */
Himani Chawla4d908332020-08-31 12:30:20 +05301211 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001212 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001213 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001214}
1215
Himani Chawla6d2ae152020-09-02 13:11:20 +05301216// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001217// #################################################################################
1218
1219// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301220// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001221
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001222//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001224 dh.lockDevice.RLock()
1225 pOnuDeviceEntry := dh.pOnuOmciDevice
1226 if aWait && pOnuDeviceEntry == nil {
1227 //keep the read sema short to allow for subsequent write
1228 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001230 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1231 // so it might be needed to wait here for that event with some timeout
1232 select {
1233 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001234 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001235 return nil
1236 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001238 // if written now, we can return the written value without sema
1239 return dh.pOnuOmciDevice
1240 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001241 }
mpagenko3af1f032020-06-10 08:53:41 +00001242 dh.lockDevice.RUnlock()
1243 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001244}
1245
Himani Chawla6d2ae152020-09-02 13:11:20 +05301246//setOnuDeviceEntry sets the ONU device entry within the handler
1247func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301248 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001249 dh.lockDevice.Lock()
1250 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001251 dh.pOnuOmciDevice = apDeviceEntry
1252 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001253 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301254 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001255}
1256
Himani Chawla6d2ae152020-09-02 13:11:20 +05301257//addOnuDeviceEntry creates a new ONU device or returns the existing
1258func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260
dbainbri4d3a0dc2020-12-02 00:33:42 +00001261 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001262 if deviceEntry == nil {
1263 /* costum_me_map in python code seems always to be None,
1264 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1265 /* also no 'clock' argument - usage open ...*/
1266 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001267 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001268 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001269 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301270 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001271 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301272 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001273 // fire deviceEntry ready event to spread to possibly waiting processing
1274 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001275 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001276 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001277 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001278 }
1279 // might be updated with some error handling !!!
1280 return nil
1281}
1282
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1284 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001285 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1286
1287 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001288
dbainbri4d3a0dc2020-12-02 00:33:42 +00001289 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001290 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001292 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1293 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001294 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 if err := dh.storePersistentData(ctx); err != nil {
1296 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001297 log.Fields{"device-id": dh.deviceID, "err": err})
1298 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001299 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001300 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001302 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1303 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001304 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001305 }
1306 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001307 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001308 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001309
1310 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001311 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 +00001312 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001313 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001314 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001315 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001316 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1317 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1318 // 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 +00001319 // 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 +00001320 // so let's just try to keep it simple ...
1321 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001323 if err != nil || device == nil {
1324 //TODO: needs to handle error scenarios
1325 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1326 return errors.New("Voltha Device not found")
1327 }
1328 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329
dbainbri4d3a0dc2020-12-02 00:33:42 +00001330 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001331 return err
mpagenko3af1f032020-06-10 08:53:41 +00001332 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001333
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001334 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001335
1336 /* this might be a good time for Omci Verify message? */
1337 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001338 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001339 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001340 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342
1343 /* give the handler some time here to wait for the OMCi verification result
1344 after Timeout start and try MibUpload FSM anyway
1345 (to prevent stopping on just not supported OMCI verification from ONU) */
1346 select {
1347 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001348 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001349 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001350 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001351 }
1352
1353 /* In py code it looks earlier (on activate ..)
1354 # Code to Run OMCI Test Action
1355 kwargs_omci_test_action = {
1356 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1357 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1358 }
1359 serial_number = device.serial_number
1360 self._test_request = OmciTestRequest(self.core_proxy,
1361 self.omci_agent, self.device_id,
1362 AniG, serial_number,
1363 self.logical_device_id,
1364 exclusive=False,
1365 **kwargs_omci_test_action)
1366 ...
1367 # Start test requests after a brief pause
1368 if not self._test_request_started:
1369 self._test_request_started = True
1370 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1371 reactor.callLater(tststart, self._test_request.start_collector)
1372
1373 */
1374 /* which is then: in omci_test_request.py : */
1375 /*
1376 def start_collector(self, callback=None):
1377 """
1378 Start the collection loop for an adapter if the frequency > 0
1379
1380 :param callback: (callable) Function to call to collect PM data
1381 """
1382 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1383 if callback is None:
1384 callback = self.perform_test_omci
1385
1386 if self.lc is None:
1387 self.lc = LoopingCall(callback)
1388
1389 if self.default_freq > 0:
1390 self.lc.start(interval=self.default_freq / 10)
1391
1392 def perform_test_omci(self):
1393 """
1394 Perform the initial test request
1395 """
1396 ani_g_entities = self._device.configuration.ani_g_entities
1397 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1398 is not None else None
1399 self._entity_id = ani_g_entities_ids[0]
1400 self.logger.info('perform-test', entity_class=self._entity_class,
1401 entity_id=self._entity_id)
1402 try:
1403 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1404 result = yield self._device.omci_cc.send(frame)
1405 if not result.fields['omci_message'].fields['success_code']:
1406 self.logger.info('Self-Test Submitted Successfully',
1407 code=result.fields[
1408 'omci_message'].fields['success_code'])
1409 else:
1410 raise TestFailure('Test Failure: {}'.format(
1411 result.fields['omci_message'].fields['success_code']))
1412 except TimeoutError as e:
1413 self.deferred.errback(failure.Failure(e))
1414
1415 except Exception as e:
1416 self.logger.exception('perform-test-Error', e=e,
1417 class_id=self._entity_class,
1418 entity_id=self._entity_id)
1419 self.deferred.errback(failure.Failure(e))
1420
1421 */
1422
1423 // PM related heartbeat??? !!!TODO....
1424 //self._heartbeat.enabled = True
1425
mpagenko1cc3cb42020-07-27 15:24:38 +00001426 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1427 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1428 * 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 +05301429 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001430 */
1431 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001432 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001433 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001434 if pMibUlFsm.Is(ulStDisabled) {
1435 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 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 +00001437 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301438 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301440 //Determine ONU status and start/re-start MIB Synchronization tasks
1441 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001442 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301443 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 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 +00001445 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001446 }
Himani Chawla4d908332020-08-31 12:30:20 +05301447 } else {
1448 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001449 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 +00001450 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301451 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001452 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001453 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001454 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001456 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001457 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001458 }
1459 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001461 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001462 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001463
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001464 if !dh.getCollectorIsRunning() {
1465 // Start PM collector routine
1466 go dh.startCollector(ctx)
1467 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301468 if !dh.getAlarmManagerIsRunning() {
1469 go dh.startAlarmManager(ctx)
1470 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301471
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001472 return nil
1473}
1474
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001476 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001477 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001478 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001480
mpagenko900ee4b2020-10-12 11:56:34 +00001481 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1482 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1483 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001484 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001485 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001486 log.Fields{"device-id": dh.deviceID, "error": err})
1487 // abort: system behavior is just unstable ...
1488 return err
1489 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001490 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001491 _ = 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 +00001492
1493 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1494 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1495 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001497 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001498 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001499 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001500 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001502
1503 //TODO!!! remove existing traffic profiles
1504 /* from py code, if TP's exist, remove them - not yet implemented
1505 self._tp = dict()
1506 # Let TP download happen again
1507 for uni_id in self._tp_service_specific_task:
1508 self._tp_service_specific_task[uni_id].clear()
1509 for uni_id in self._tech_profile_download_done:
1510 self._tech_profile_download_done[uni_id].clear()
1511 */
1512
dbainbri4d3a0dc2020-12-02 00:33:42 +00001513 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001514
mpagenkofc4f56e2020-11-04 17:17:49 +00001515 dh.ReadyForSpecificOmciConfig = false
1516
dbainbri4d3a0dc2020-12-02 00:33:42 +00001517 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001518 // abort: system behavior is just unstable ...
1519 return err
1520 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001521 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001522 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001523 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001524 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001525 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001526 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001527 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001528 // abort: system behavior is just unstable ...
1529 return err
1530 }
1531 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001532 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001533 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001534 return nil
1535}
1536
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001537func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001538 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1539 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1540 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1541 // and using the stop/reset event should never harm
1542
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001544 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001546 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1547 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001548 if includingMibSyncFsm {
1549 //the MibSync FSM might be active all the ONU-active time,
1550 // hence it must be stopped unconditionally
1551 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1552 if pMibUlFsm != nil {
1553 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1554 }
mpagenko900ee4b2020-10-12 11:56:34 +00001555 }
1556 //MibDownload may run
1557 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1558 if pMibDlFsm != nil {
1559 _ = pMibDlFsm.Event(dlEvReset)
1560 }
1561 //port lock/unlock FSM's may be active
1562 if dh.pUnlockStateFsm != nil {
1563 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1564 }
1565 if dh.pLockStateFsm != nil {
1566 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1567 }
1568 //techProfile related PonAniConfigFsm FSM may be active
1569 if dh.pOnuTP != nil {
1570 // should always be the case here
1571 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1572 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001573 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1574 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1575 }
mpagenko900ee4b2020-10-12 11:56:34 +00001576 }
1577 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001578 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001579 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001580 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00001581 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001582 //VlanFilterFsm exists and was already started
1583 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1584 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001585 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001586 // no need to remove specific data
1587 pVlanFilterFsm.RequestClearPersistency(false)
1588 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001589 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1590 }
mpagenkof1fc3862021-02-16 10:09:52 +00001591 } else {
1592 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001593 }
1594 }
1595 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001596 if dh.getCollectorIsRunning() {
1597 // Stop collector routine
1598 dh.stopCollector <- true
1599 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301600 if dh.getAlarmManagerIsRunning() {
1601 dh.stopAlarmManager <- true
1602 }
1603
mpagenko900ee4b2020-10-12 11:56:34 +00001604 return nil
1605}
1606
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1608 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 +05301609
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001610 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001612 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001614 return
1615 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001616 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001617 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1618 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1619 for _, mgmtEntityID := range pptpInstKeys {
1620 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1621 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301623 i++
1624 }
1625 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301627 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001628 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1629 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301630 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001631 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301632 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301634 i++
1635 }
1636 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301638 }
1639 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301641 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001642 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1643 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1644 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1645 * disable/enable toggling here to allow traffic
1646 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1647 * like the py comment says:
1648 * # start by locking all the unis till mib sync and initial mib is downloaded
1649 * # this way we can capture the port down/up events when we are ready
1650 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301651
mpagenkoa40e99a2020-11-17 13:50:39 +00001652 // Init Uni Ports to Admin locked state
1653 // *** should generate UniLockStateDone event *****
1654 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001656 } else { //LockStateFSM already init
1657 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001658 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001659 }
1660}
1661
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1663 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301664 /* Mib download procedure -
1665 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1666 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001668 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001670 return
1671 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301672 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1673 if pMibDlFsm != nil {
1674 if pMibDlFsm.Is(dlStDisabled) {
1675 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676 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 +05301677 // maybe try a FSM reset and then again ... - TODO!!!
1678 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301680 // maybe use more specific states here for the specific download steps ...
1681 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301683 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301685 //Begin MIB data download (running autonomously)
1686 }
1687 }
1688 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001690 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301691 // maybe try a FSM reset and then again ... - TODO!!!
1692 }
1693 /***** Mib download started */
1694 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301696 }
1697}
1698
dbainbri4d3a0dc2020-12-02 00:33:42 +00001699func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1700 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301701 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001702 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001704 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301706 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1707 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301709 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301711 }
1712 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001714 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001716 return
1717 }
1718 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 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 +00001720 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001721 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001722 return
1723 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301725 log.Fields{"device-id": dh.deviceID})
1726 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001727 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001728
1729 // Initialize classical L2 PM Interval Counters
1730 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1731 // There is no way we should be landing here, but if we do then
1732 // there is nothing much we can do about this other than log error
1733 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1734 }
1735
mpagenkofc4f56e2020-11-04 17:17:49 +00001736 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301737 // *** should generate UniUnlockStateDone event *****
1738 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301740 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301741 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301743 }
1744}
1745
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1747 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301748
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001749 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301751 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1753 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001754 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001756 return
1757 }
1758 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 if err := dh.storePersistentData(ctx); err != nil {
1760 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001761 log.Fields{"device-id": dh.deviceID, "err": err})
1762 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301763 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764 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 +05301765 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001767 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301768 }
1769}
1770
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1772 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001773 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001775 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1776 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001778 }
1779
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001781 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001783
1784 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001786
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001788 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001790 return
1791 }
1792 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 if err := dh.storePersistentData(ctx); err != nil {
1794 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001795 log.Fields{"device-id": dh.deviceID, "err": err})
1796 }
mpagenko900ee4b2020-10-12 11:56:34 +00001797}
1798
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1800 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001801 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001803 voltha.OperStatus_ACTIVE); err != nil {
1804 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001806 }
1807
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001809 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001810 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001812
1813 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001815
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001817 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001819 return
1820 }
1821 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822 if err := dh.storePersistentData(ctx); err != nil {
1823 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001824 log.Fields{"device-id": dh.deviceID, "err": err})
1825 }
mpagenko900ee4b2020-10-12 11:56:34 +00001826}
1827
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001829 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001831 // attention: the device reason update is done based on ONU-UNI-Port related activity
1832 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001833 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001834 // 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 +00001835 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301836 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001837 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001838 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001839 }
1840 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001842 // attention: the device reason update is done based on ONU-UNI-Port related activity
1843 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001844 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001845 // 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 +00001846 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001847 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001848 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301849}
1850
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1852 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001853 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301854 // attention: the device reason update is done based on ONU-UNI-Port related activity
1855 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301856
mpagenkof1fc3862021-02-16 10:09:52 +00001857 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001858 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001859 // which may be the case from some previous actvity on another UNI Port of the ONU
1860 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001861 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1862 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001864 }
1865 }
1866 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001867 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001868 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001870 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301871 }
mpagenkof1fc3862021-02-16 10:09:52 +00001872
1873 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1874 //events that request KvStore write
1875 if err := dh.storePersistentData(ctx); err != nil {
1876 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1877 log.Fields{"device-id": dh.deviceID, "err": err})
1878 }
1879 } else {
1880 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
1881 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001882 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301883}
1884
Himani Chawla6d2ae152020-09-02 13:11:20 +05301885//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301887 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001888 case MibDatabaseSync:
1889 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001891 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001892 case UniLockStateDone:
1893 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001895 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001896 case MibDownloadDone:
1897 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001899 }
1900 case UniUnlockStateDone:
1901 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001903 }
mpagenko900ee4b2020-10-12 11:56:34 +00001904 case UniEnableStateDone:
1905 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001907 }
1908 case UniDisableStateDone:
1909 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001911 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001912 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001913 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001915 }
mpagenkof1fc3862021-02-16 10:09:52 +00001916 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00001917 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001919 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001920 default:
1921 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001923 }
1924 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001925}
1926
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001928 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301930 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001931 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001933 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301934 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001936 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001939 //store UniPort with the System-PortNumber key
1940 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001941 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001942 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1944 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001945 } //error logging already within UniPort method
1946 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001947 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001948 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001949 }
1950 }
1951}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001952
mpagenko3af1f032020-06-10 08:53:41 +00001953// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001955 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301956 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001957 // with following remark:
1958 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1959 // # load on the core
1960
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001961 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001962
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001963 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001964 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301965 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301967 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001968 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001969 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 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 +00001971 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001972 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001974 }
mpagenko3af1f032020-06-10 08:53:41 +00001975 }
1976 }
1977}
1978
1979// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001981 // compare enableUniPortStateUpdate() above
1982 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1983 for uniNo, uniPort := range dh.uniEntityMap {
1984 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301985 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301987 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001988 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 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 +00001990 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001991 }
1992}
1993
1994// ONU_Active/Inactive announcement on system KAFKA bus
1995// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001997 var de voltha.DeviceEvent
1998 eventContext := make(map[string]string)
1999 //Populating event context
2000 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002002 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302004 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002005 }
2006 oltSerialNumber := parentDevice.SerialNumber
2007
2008 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2009 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2010 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302011 eventContext["olt-serial-number"] = oltSerialNumber
2012 eventContext["device-id"] = aDeviceID
2013 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002015 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002016
2017 /* Populating device event body */
2018 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302019 de.ResourceId = aDeviceID
2020 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002021 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2022 de.Description = fmt.Sprintf("%s Event - %s - %s",
2023 cEventObjectType, cOnuActivatedEvent, "Raised")
2024 } else {
2025 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2026 de.Description = fmt.Sprintf("%s Event - %s - %s",
2027 cEventObjectType, cOnuActivatedEvent, "Cleared")
2028 }
2029 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002030 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2031 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302032 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002033 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002034 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302035 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002036}
2037
Himani Chawla4d908332020-08-31 12:30:20 +05302038// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002040 chLSFsm := make(chan Message, 2048)
2041 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302042 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002044 sFsmName = "LockStateFSM"
2045 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002047 sFsmName = "UnLockStateFSM"
2048 }
mpagenko3af1f032020-06-10 08:53:41 +00002049
dbainbri4d3a0dc2020-12-02 00:33:42 +00002050 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002051 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002053 return
2054 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002056 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002057 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302058 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002059 dh.pLockStateFsm = pLSFsm
2060 } else {
2061 dh.pUnlockStateFsm = pLSFsm
2062 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002064 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002065 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002066 }
2067}
2068
2069// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002071 /* Uni Port lock/unlock procedure -
2072 ***** should run via 'adminDone' state and generate the argument requested event *****
2073 */
2074 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302075 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002076 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2077 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2078 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002079 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302080 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002081 }
2082 } else {
2083 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2084 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2085 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002086 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302087 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002088 }
2089 }
2090 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002091 if pLSStatemachine.Is(uniStDisabled) {
2092 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002094 // maybe try a FSM reset and then again ... - TODO!!!
2095 } else {
2096 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002097 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002098 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002099 }
2100 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002101 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002102 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002103 // maybe try a FSM reset and then again ... - TODO!!!
2104 }
2105 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002106 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002107 // maybe try a FSM reset and then again ... - TODO!!!
2108 }
2109}
2110
Himani Chawla6d2ae152020-09-02 13:11:20 +05302111//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002112func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002113
2114 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002115 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002116 kvbackend := &db.Backend{
2117 Client: dh.pOpenOnuAc.kvClient,
2118 StoreType: dh.pOpenOnuAc.KVStoreType,
2119 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002120 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002121 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2122 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002123
mpagenkoaf801632020-07-03 10:00:42 +00002124 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002125}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302127 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002128
mpagenkodff5dda2020-08-28 11:52:01 +00002129 for _, field := range flow.GetOfbFields(apFlowItem) {
2130 switch field.Type {
2131 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2132 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002134 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2135 }
mpagenko01e726e2020-10-23 09:45:29 +00002136 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002137 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2138 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302139 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002140 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302141 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2142 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002143 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2144 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002145 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2146 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302147 return
mpagenkodff5dda2020-08-28 11:52:01 +00002148 }
2149 }
mpagenko01e726e2020-10-23 09:45:29 +00002150 */
mpagenkodff5dda2020-08-28 11:52:01 +00002151 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2152 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302153 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002154 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302155 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002156 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002158 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302160 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002161 }
2162 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2163 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302164 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002166 "PCP": loAddPcp})
2167 }
2168 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2169 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002171 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2172 }
2173 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2174 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002176 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2177 }
2178 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2179 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002181 "IPv4-DST": field.GetIpv4Dst()})
2182 }
2183 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2184 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002186 "IPv4-SRC": field.GetIpv4Src()})
2187 }
2188 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2189 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002191 "Metadata": field.GetTableMetadata()})
2192 }
2193 /*
2194 default:
2195 {
2196 //all other entires ignored
2197 }
2198 */
2199 }
2200 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302201}
mpagenkodff5dda2020-08-28 11:52:01 +00002202
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002204 for _, action := range flow.GetActions(apFlowItem) {
2205 switch action.Type {
2206 /* not used:
2207 case of.OfpActionType_OFPAT_OUTPUT:
2208 {
mpagenko01e726e2020-10-23 09:45:29 +00002209 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002210 "Output": action.GetOutput()})
2211 }
2212 */
2213 case of.OfpActionType_OFPAT_PUSH_VLAN:
2214 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002216 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2217 }
2218 case of.OfpActionType_OFPAT_SET_FIELD:
2219 {
2220 pActionSetField := action.GetSetField()
2221 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002223 "OxcmClass": pActionSetField.Field.OxmClass})
2224 }
2225 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302226 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302228 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002229 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302230 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302232 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002233 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002235 "Type": pActionSetField.Field.GetOfbField().Type})
2236 }
2237 }
2238 /*
2239 default:
2240 {
2241 //all other entires ignored
2242 }
2243 */
2244 }
2245 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302246}
2247
2248//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302250 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2251 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2252 var loAddPcp, loSetPcp uint8
2253 var loIPProto uint32
2254 /* the TechProfileId is part of the flow Metadata - compare also comment within
2255 * OLT-Adapter:openolt_flowmgr.go
2256 * Metadata 8 bytes:
2257 * Most Significant 2 Bytes = Inner VLAN
2258 * Next 2 Bytes = Tech Profile ID(TPID)
2259 * Least Significant 4 Bytes = Port ID
2260 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2261 * subscriber related flows.
2262 */
2263
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302265 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302267 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002268 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302269 }
mpagenko551a4d42020-12-08 18:09:20 +00002270 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002271 loCookie := apFlowItem.GetCookie()
2272 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002273 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002274 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302275
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002277 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302278 if loIPProto == 2 {
2279 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2280 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002281 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2282 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302283 return nil
2284 }
mpagenko01e726e2020-10-23 09:45:29 +00002285 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002287
2288 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002290 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2291 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2292 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2293 //TODO!!: Use DeviceId within the error response to rwCore
2294 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002295 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002296 }
2297 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002299 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2300 } else {
2301 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2302 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2303 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302304 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002305 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002307 }
mpagenko9a304ea2020-12-16 15:54:01 +00002308
2309 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002310 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002311 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302312 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002313 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002314 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002315 dh.lockVlanConfig.RUnlock()
2316 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002317 }
mpagenkof1fc3862021-02-16 10:09:52 +00002318 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002320 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002321}
2322
2323//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002325 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2326 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2327 //no extra check is done on the rule parameters
2328 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2329 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2330 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2331 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002332 // - 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 +00002333 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002335
2336 /* TT related temporary workaround - should not be needed anymore
2337 for _, field := range flow.GetOfbFields(apFlowItem) {
2338 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2339 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002340 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002341 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2342 if loIPProto == 2 {
2343 // 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 +00002344 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002345 log.Fields{"device-id": dh.deviceID})
2346 return nil
2347 }
2348 }
2349 } //for all OfbFields
2350 */
2351
mpagenko9a304ea2020-12-16 15:54:01 +00002352 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002353 dh.lockVlanConfig.RLock()
2354 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002355 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002357 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002359 log.Fields{"device-id": dh.deviceID})
2360 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002361 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002363
mpagenko01e726e2020-10-23 09:45:29 +00002364 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002365}
2366
Himani Chawla26e555c2020-08-31 12:30:20 +05302367// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002368// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002369func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002370 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002371 chVlanFilterFsm := make(chan Message, 2048)
2372
dbainbri4d3a0dc2020-12-02 00:33:42 +00002373 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002374 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302376 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002377 }
2378
dbainbri4d3a0dc2020-12-02 00:33:42 +00002379 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002380 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2381 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002382 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002383 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302384 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002385 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002386 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2387 if pVlanFilterStatemachine != nil {
2388 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2389 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302391 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002392 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302393 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302395 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2396 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002399 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302400 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002401 }
2402 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002404 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302405 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002406 }
2407 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002408 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002409 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302410 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002411 }
2412 return nil
2413}
2414
mpagenkofc4f56e2020-11-04 17:17:49 +00002415//VerifyVlanConfigRequest checks on existence of a given uniPort
2416// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002417func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002418 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2419 var pCurrentUniPort *onuUniPort
2420 for _, uniPort := range dh.uniEntityMap {
2421 // only if this port is validated for operState transfer
2422 if uniPort.uniID == uint8(aUniID) {
2423 pCurrentUniPort = uniPort
2424 break //found - end search loop
2425 }
2426 }
2427 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002429 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2430 return
2431 }
mpagenko551a4d42020-12-08 18:09:20 +00002432 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002433}
2434
mpagenkodff5dda2020-08-28 11:52:01 +00002435//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002436func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002437 //TODO!! verify and start pending flow configuration
2438 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2439 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002440
2441 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302442 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002443 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002444 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2445 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2446 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002447 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2448 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2449 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2450 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2451 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2452 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2453 } else {
2454 /***** UniVlanConfigFsm continued */
2455 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2456 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2457 "UniPort": apUniPort.portNo})
2458 }
2459 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2460 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2461 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2462 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2463 } else {
2464 /***** UniVlanConfigFsm continued */
2465 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2466 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2467 "UniPort": apUniPort.portNo})
2468 }
mpagenkodff5dda2020-08-28 11:52:01 +00002469 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002470 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2471 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002472 "UniPort": apUniPort.portNo})
2473 }
2474 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002475 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2476 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2477 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002478 }
2479 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002480 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002481 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002482 }
mpagenkof1fc3862021-02-16 10:09:52 +00002483 } else {
2484 dh.lockVlanConfig.RUnlock()
2485 }
mpagenkodff5dda2020-08-28 11:52:01 +00002486}
2487
2488//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2489// 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 +00002490func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2491 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002492 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2493 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002494 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302495 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002496 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002497}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002498
Girish Gowdra26a40922021-01-29 17:14:34 -08002499//ProcessPendingTpDelete processes any pending TP delete (if available)
2500func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2501 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2502 if apUniPort == nil {
2503 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2504 return
2505 }
2506 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2507 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2508 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2509 if pAniConfigStatemachine != nil {
2510 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2511 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2512 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2513 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2514 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2515 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2516 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2517 return
2518 }
2519 } else {
2520 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2521 return
2522 }
2523 }
2524 return
2525 }
2526}
2527
mpagenkof1fc3862021-02-16 10:09:52 +00002528//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2529func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2530 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2531 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2532 // obviously then parallel processing on the cancel must be avoided
2533 // deadline context to ensure completion of background routines waited for
2534 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2535 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2536 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2537
2538 aPDevEntry.resetKvProcessingErrorIndication()
2539 var wg sync.WaitGroup
2540 wg.Add(1) // for the 1 go routine to finish
2541
2542 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2543 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2544
2545 return aPDevEntry.getKvProcessingErrorIndication()
2546}
2547
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002548//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2549//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002550func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2551 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002552
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002553 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002554 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002555 return nil
2556 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002558
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002560 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002561 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002562 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2563 }
2564 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2565
mpagenkof1fc3862021-02-16 10:09:52 +00002566 if aWriteToKvStore {
2567 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2568 }
2569 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002570}
2571
dbainbri4d3a0dc2020-12-02 00:33:42 +00002572func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002573 defer cancel() //ensure termination of context (may be pro forma)
2574 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002575 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002576 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002577}
2578
dbainbri4d3a0dc2020-12-02 00:33:42 +00002579func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002580
2581 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002582 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002583 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002584 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2585 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002586 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002587 return err
2588 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002589 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002590 return nil
2591 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002592 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002593 return nil
2594}
2595
dbainbri4d3a0dc2020-12-02 00:33:42 +00002596func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2597 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002598 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002599 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002600 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2601 }
mpagenkof1fc3862021-02-16 10:09:52 +00002602 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002603}
2604
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002605func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2606 var errStr string = ""
2607 for _, err := range errS {
2608 if err != nil {
2609 errStr = errStr + err.Error() + " "
2610 }
2611 }
2612 if errStr != "" {
2613 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2614 }
2615 return nil
2616}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002617
2618// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2619func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2620 dh.lockDevice.RLock()
2621 defer dh.lockDevice.RUnlock()
2622 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2623 return uniPort.entityID, nil
2624 }
2625 return 0, errors.New("error-fetching-uni-port")
2626}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002627
2628// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002629func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2630 var errorsList []error
2631 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 -08002632
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002633 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2634 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2635 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2636
2637 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2638 // successfully.
2639 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2640 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2641 if len(errorsList) > 0 {
2642 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2643 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002644 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002645 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2646 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002647}
2648
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002649func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2650 var err error
2651 var errorsList []error
2652 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2653
2654 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2655 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2656 errorsList = append(errorsList, err)
2657 }
2658 }
2659
2660 return errorsList
2661}
2662
2663func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2664 var err error
2665 var errorsList []error
2666 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2667 // Check if group metric related config is updated
2668 for _, v := range pmConfigs.Groups {
2669 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2670 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2671 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2672
2673 if ok && m.frequency != v.GroupFreq {
2674 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2675 errorsList = append(errorsList, err)
2676 }
2677 }
2678 if ok && m.enabled != v.Enabled {
2679 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2680 errorsList = append(errorsList, err)
2681 }
2682 }
2683 }
2684 return errorsList
2685}
2686
2687func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2688 var err error
2689 var errorsList []error
2690 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2691 // Check if standalone metric related config is updated
2692 for _, v := range pmConfigs.Metrics {
2693 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002694 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002695 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2696
2697 if ok && m.frequency != v.SampleFreq {
2698 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2699 errorsList = append(errorsList, err)
2700 }
2701 }
2702 if ok && m.enabled != v.Enabled {
2703 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2704 errorsList = append(errorsList, err)
2705 }
2706 }
2707 }
2708 return errorsList
2709}
2710
2711// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002712func (dh *deviceHandler) startCollector(ctx context.Context) {
2713 logger.Debugf(ctx, "startingCollector")
2714
2715 // Start routine to process OMCI GET Responses
2716 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002717 // Initialize the next metric collection time.
2718 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2719 // reset like onu rebooted.
2720 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002721 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002722 for {
2723 select {
2724 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002725 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002726 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002727 // Stop the L2 PM FSM
2728 go func() {
2729 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2730 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2731 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2732 }
2733 } else {
2734 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2735 }
2736 }()
2737
Girish Gowdrae09a6202021-01-12 18:10:59 -08002738 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002739 dh.pOnuMetricsMgr.stopTicks <- true
2740
Girish Gowdrae09a6202021-01-12 18:10:59 -08002741 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002742 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2743 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2744 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2745 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2746 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002747 // Update the next metric collection time.
2748 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002749 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002750 } else {
2751 if dh.pmConfigs.Grouped { // metrics are managed as a group
2752 // parse through the group and standalone metrics to see it is time to collect their metrics
2753 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002754
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002755 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2756 // 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 -08002757 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2758 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002759 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2760 }
2761 }
2762 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2763 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2764 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2765 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2766 }
2767 }
2768 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2769
2770 // parse through the group and update the next metric collection time
2771 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2772 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2773 // 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 -08002774 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2775 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002776 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2777 }
2778 }
2779 // parse through the standalone metrics and update the next metric collection time
2780 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2781 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2782 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2783 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2784 }
2785 }
2786 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2787 } /* else { // metrics are not managed as a group
2788 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2789 } */
2790 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002791 }
2792 }
2793}
kesavandfdf77632021-01-26 23:40:33 -05002794
2795func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2796
2797 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2798 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2799}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002800
mpagenkof1fc3862021-02-16 10:09:52 +00002801func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2802 if pFsm == nil {
2803 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002804 }
mpagenkof1fc3862021-02-16 10:09:52 +00002805 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002806}
2807
mpagenkof1fc3862021-02-16 10:09:52 +00002808func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
2809 var pFsm *fsm.FSM
2810 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
2811 switch omciFsm {
2812 case cUploadFsm:
2813 {
2814 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
2815 }
2816 case cDownloadFsm:
2817 {
2818 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
2819 }
2820 case cUniLockFsm:
2821 {
2822 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
2823 }
2824 case cUniUnLockFsm:
2825 {
2826 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2827 }
2828 case cL2PmFsm:
2829 {
2830 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
2831 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
2832 } else {
2833 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002834 }
2835 }
mpagenkof1fc3862021-02-16 10:09:52 +00002836 default:
2837 {
2838 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
2839 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
2840 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002841 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002842 }
mpagenkof1fc3862021-02-16 10:09:52 +00002843 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002844}
2845
mpagenkof1fc3862021-02-16 10:09:52 +00002846func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
2847 for _, v := range dh.pOnuTP.pAniConfigFsm {
2848 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002849 return false
2850 }
2851 }
2852 return true
2853}
2854
mpagenkof1fc3862021-02-16 10:09:52 +00002855func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
2856 dh.lockVlanConfig.RLock()
2857 defer dh.lockVlanConfig.RUnlock()
2858 for _, v := range dh.UniVlanConfigFsmMap {
2859 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
2860 return false
2861 }
2862 }
2863 return true //FSM not active - so there is no activity on omci
2864}
2865
2866func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
2867 dh.lockVlanConfig.RLock()
2868 defer dh.lockVlanConfig.RUnlock()
2869 for _, v := range dh.UniVlanConfigFsmMap {
2870 if v.pAdaptFsm.pFsm != nil {
2871 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
2872 return true //there is at least one VLAN FSM with some active configuration
2873 }
2874 }
2875 }
2876 return false //there is no VLAN FSM with some active configuration
2877}
2878
2879func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
2880 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
2881 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
2882 return false
2883 }
2884 }
2885 // a further check is done to identify, if at least some data traffic related configuration exists
2886 // so that a user of this ONU could be 'online' (otherwise it makes no sense to check the MDS [with the intention to keep the user service up])
2887 return dh.checkUserServiceExists(ctx)
2888}
2889
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002890func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
2891 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
2892 if err := dh.resetFsms(ctx, false); err != nil {
2893 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
2894 // TODO: fatal error reset ONU, delete deviceHandler!
2895 return
2896 }
2897 if !dh.getCollectorIsRunning() {
2898 // Start PM collector routine
2899 go dh.startCollector(ctx)
2900 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302901 if !dh.getAlarmManagerIsRunning() {
2902 go dh.startAlarmManager(ctx)
2903 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002904 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002905 dh.startReconciling(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002906}
2907
2908func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
2909 dh.mutexCollectorFlag.Lock()
2910 dh.collectorIsRunning = flagValue
2911 dh.mutexCollectorFlag.Unlock()
2912}
2913
2914func (dh *deviceHandler) getCollectorIsRunning() bool {
2915 dh.mutexCollectorFlag.RLock()
2916 flagValue := dh.collectorIsRunning
2917 dh.mutexCollectorFlag.RUnlock()
2918 return flagValue
2919}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302920
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302921func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
2922 dh.mutextAlarmManagerFlag.Lock()
2923 dh.alarmManagerIsRunning = flagValue
2924 dh.mutextAlarmManagerFlag.Unlock()
2925}
2926
2927func (dh *deviceHandler) getAlarmManagerIsRunning() bool {
2928 dh.mutextAlarmManagerFlag.RLock()
2929 flagValue := dh.alarmManagerIsRunning
2930 dh.mutextAlarmManagerFlag.RUnlock()
2931 return flagValue
2932}
2933
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302934func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
2935 logger.Debugf(ctx, "startingAlarmManager")
2936
2937 // Start routine to process OMCI GET Responses
2938 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302939 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302940 if stop := <-dh.stopAlarmManager; stop {
2941 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2942 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302943 dh.setAlarmManagerIsRunning(false)
2944
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302945 }
2946}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00002947
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002948func (dh *deviceHandler) startReconciling(ctx context.Context) {
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00002949 logger.Debugw(ctx, "start reconciling", log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002950 if !dh.isReconciling() {
2951 go func() {
2952 select {
2953 case <-dh.chReconcilingFinished:
2954 logger.Debugw(ctx, "reconciling has been finished in time",
2955 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00002956 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002957 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
2958 log.Fields{"device-id": dh.deviceID})
2959 }
2960 dh.mutexReconcilingFlag.Lock()
2961 dh.reconciling = false
2962 dh.mutexReconcilingFlag.Unlock()
2963 }()
2964 dh.mutexReconcilingFlag.Lock()
2965 dh.reconciling = true
2966 dh.mutexReconcilingFlag.Unlock()
2967 } else {
2968 logger.Warnw(ctx, "reconciling is already running", log.Fields{"device-id": dh.deviceID})
2969 }
2970}
2971
2972func (dh *deviceHandler) stopReconciling(ctx context.Context) {
2973 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
2974 if dh.isReconciling() {
2975 dh.chReconcilingFinished <- true
2976 } else {
2977 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
2978 }
2979}
2980
2981func (dh *deviceHandler) isReconciling() bool {
2982 dh.mutexReconcilingFlag.RLock()
2983 value := dh.reconciling
2984 dh.mutexReconcilingFlag.RUnlock()
2985 return value
2986}