blob: f690e384a35216fbf460bc102b40dcfa160dca9b [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 Hildebrandt80129db2020-11-23 10:49:32 +000095const (
96 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +000097 drUnset = 0
98 drActivatingOnu = 1
99 drStartingOpenomci = 2
100 drDiscoveryMibsyncComplete = 3
101 drInitialMibDownloaded = 4
102 drTechProfileConfigDownloadSuccess = 5
103 drOmciFlowsPushed = 6
104 drOmciAdminLock = 7
105 drOnuReenabled = 8
106 drStoppingOpenomci = 9
107 drRebooting = 10
108 drOmciFlowsDeleted = 11
109 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000110)
111
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000112var deviceReasonMap = map[uint8]string{
113 drUnset: "unset",
114 drActivatingOnu: "activating-onu",
115 drStartingOpenomci: "starting-openomci",
116 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
117 drInitialMibDownloaded: "initial-mib-downloaded",
118 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
119 drOmciFlowsPushed: "omci-flows-pushed",
120 drOmciAdminLock: "omci-admin-lock",
121 drOnuReenabled: "onu-reenabled",
122 drStoppingOpenomci: "stopping-openomci",
123 drRebooting: "rebooting",
124 drOmciFlowsDeleted: "omci-flows-deleted",
125 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
126}
127
Himani Chawla6d2ae152020-09-02 13:11:20 +0530128//deviceHandler will interact with the ONU ? device.
129type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000130 deviceID string
131 DeviceType string
132 adminState string
133 device *voltha.Device
134 logicalDeviceID string
135 ProxyAddressID string
136 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530137 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000138 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000139
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000140 coreProxy adapterif.CoreProxy
141 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530142 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000143
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800144 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800145
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000146 pOpenOnuAc *OpenONUAC
147 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530148 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000149 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000150 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530151 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800152 pOnuMetricsMgr *onuMetricsManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153 exitChannel chan int
154 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000155 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000156 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530157 pLockStateFsm *lockStateFsm
158 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000159
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160 //flowMgr *OpenOltFlowMgr
161 //eventMgr *OpenOltEventMgr
162 //resourceMgr *rsrcMgr.OpenOltResourceMgr
163
164 //discOnus sync.Map
165 //onus sync.Map
166 //portStats *OpenOltStatisticsMgr
mpagenkofc4f56e2020-11-04 17:17:49 +0000167 stopCollector chan bool
168 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000169 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000170 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000171 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
172 reconciling bool
173 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000174}
175
Himani Chawla6d2ae152020-09-02 13:11:20 +0530176//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530177func 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 +0530178 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000179 dh.coreProxy = cp
180 dh.AdapterProxy = ap
181 dh.EventProxy = ep
182 cloned := (proto.Clone(device)).(*voltha.Device)
183 dh.deviceID = cloned.Id
184 dh.DeviceType = cloned.Type
185 dh.adminState = "up"
186 dh.device = cloned
187 dh.pOpenOnuAc = adapter
188 dh.exitChannel = make(chan int, 1)
189 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000190 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000191 dh.stopCollector = make(chan bool, 2)
192 dh.stopHeartbeatCheck = make(chan bool, 2)
193 //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 +0000194 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530195 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000196 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000197 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000198 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000199 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000200
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800201 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
202 dh.pmConfigs = cloned.PmConfigs
203 } /* else {
204 // will be populated when onu_metrics_mananger is initialized.
205 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800206
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000207 // Device related state machine
208 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000209 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000211 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
212 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
213 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
214 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
215 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000216 },
217 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000218 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
219 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
220 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
221 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
222 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
223 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
224 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
225 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000226 },
227 )
mpagenkoaf801632020-07-03 10:00:42 +0000228
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000229 return &dh
230}
231
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232// start save the device to the data model
233func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000234 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000236 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
Himani Chawla4d908332020-08-31 12:30:20 +0530239/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 logger.Debug("stopping-device-handler")
243 dh.exitChannel <- 1
244}
Himani Chawla4d908332020-08-31 12:30:20 +0530245*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246
247// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530248// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249
Himani Chawla6d2ae152020-09-02 13:11:20 +0530250//adoptOrReconcileDevice adopts the OLT device
251func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000252 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000253
dbainbri4d3a0dc2020-12-02 00:33:42 +0000254 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000255 if dh.pDeviceStateFsm.Is(devStNull) {
256 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000257 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000259 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800260 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
261 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800262 // Now, set the initial PM configuration for that device
263 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
264 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
265 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800266 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000268 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269 }
270
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000271}
272
mpagenko057889c2021-01-21 16:51:58 +0000273func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530274 msgBody := msg.GetBody()
275 omciMsg := &ic.InterAdapterOmciMessage{}
276 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530278 "device-id": dh.deviceID, "error": err})
279 return err
280 }
281
282 //assuming omci message content is hex coded!
283 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530285 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
286 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530288 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000289 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000291 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000292 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 +0530293 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000295 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530296}
297
Himani Chawla6d2ae152020-09-02 13:11:20 +0530298func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530300 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000301
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000303
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000305 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000307 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
308 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530309 if dh.pOnuTP == nil {
310 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530312 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000313 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530314 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000315 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000317 "device-state": deviceReasonMap[dh.deviceReason]})
318 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530319 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000320 //previous state test here was just this one, now extended for more states to reject the SetRequest:
321 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
322 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530323
324 msgBody := msg.GetBody()
325 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
326 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530328 "device-id": dh.deviceID, "error": err})
329 return err
330 }
331
332 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000333 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
334 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530335 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000336 defer dh.pOnuTP.unlockTpProcMutex()
337 pDevEntry.lockOnuKVStoreMutex()
338 defer pDevEntry.unlockOnuKVStoreMutex()
339
340 if techProfMsg.UniId > 255 {
341 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
342 techProfMsg.UniId, dh.deviceID))
343 }
344 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800345 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
346 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800348 return err
349 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000350
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 // if there has been some change for some uni TechProfilePath
353 //in order to allow concurrent calls to other dh instances we do not wait for execution here
354 //but doing so we can not indicate problems to the caller (who does what with that then?)
355 //by now we just assume straightforward successful execution
356 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
357 // possible problems to the caller later autonomously
358
359 // deadline context to ensure completion of background routines waited for
360 //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 +0530361 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 dctx, cancel := context.WithDeadline(context.Background(), deadline)
363
Girish Gowdra041dcb32020-11-16 16:54:30 -0800364 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 pDevEntry.resetKvProcessingErrorIndication()
366
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 var wg sync.WaitGroup
368 wg.Add(2) // for the 2 go routines to finish
369 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
371 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
372 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000373
Girish Gowdra041dcb32020-11-16 16:54:30 -0800374 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 return nil
378}
379
Himani Chawla6d2ae152020-09-02 13:11:20 +0530380func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 msg *ic.InterAdapterMessage) error {
383
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000385
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000387 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
390 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 if dh.pOnuTP == nil {
392 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000393 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
397
398 msgBody := msg.GetBody()
399 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
400 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000401 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530402 "device-id": dh.deviceID, "error": err})
403 return err
404 }
405
406 //compare TECH_PROFILE_DOWNLOAD_REQUEST
407 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 defer dh.pOnuTP.unlockTpProcMutex()
409 pDevEntry.lockOnuKVStoreMutex()
410 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530411
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412 if delGemPortMsg.UniId > 255 {
413 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
414 delGemPortMsg.UniId, dh.deviceID))
415 }
416 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800417 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
418 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000419 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 -0800420 return err
421 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530422
mpagenkofc4f56e2020-11-04 17:17:49 +0000423 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424
mpagenkofc4f56e2020-11-04 17:17:49 +0000425 // deadline context to ensure completion of background routines waited for
426 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
427 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000428
Girish Gowdra041dcb32020-11-16 16:54:30 -0800429 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000430
mpagenkofc4f56e2020-11-04 17:17:49 +0000431 var wg sync.WaitGroup
432 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000434 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000435 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000436
Girish Gowdra041dcb32020-11-16 16:54:30 -0800437 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530438}
439
Himani Chawla6d2ae152020-09-02 13:11:20 +0530440func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000441 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530442 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000443
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000445
dbainbri4d3a0dc2020-12-02 00:33:42 +0000446 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000448 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000449 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
450 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530451 if dh.pOnuTP == nil {
452 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000453 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530454 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000455 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530456 }
457
458 msgBody := msg.GetBody()
459 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
460 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530462 "device-id": dh.deviceID, "error": err})
463 return err
464 }
465
466 //compare TECH_PROFILE_DOWNLOAD_REQUEST
467 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000468 defer dh.pOnuTP.unlockTpProcMutex()
469 pDevEntry.lockOnuKVStoreMutex()
470 defer pDevEntry.unlockOnuKVStoreMutex()
471
472 if delTcontMsg.UniId > 255 {
473 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
474 delTcontMsg.UniId, dh.deviceID))
475 }
476 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800477 tpPath := delTcontMsg.TpPath
478 tpID, err := GetTpIDFromTpPath(tpPath)
479 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800481 return err
482 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530486 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530487 dctx, cancel := context.WithDeadline(context.Background(), deadline)
488
Girish Gowdra041dcb32020-11-16 16:54:30 -0800489 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490 pDevEntry.resetKvProcessingErrorIndication()
491
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 var wg sync.WaitGroup
493 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000494 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 cResourceTcont, delTcontMsg.AllocId, &wg)
496 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000497 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
498 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499
Girish Gowdra041dcb32020-11-16 16:54:30 -0800500 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 return nil
503}
504
Himani Chawla6d2ae152020-09-02 13:11:20 +0530505//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000506// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
507// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000509 msgID := msg.Header.Id
510 msgType := msg.Header.Type
511 fromTopic := msg.Header.FromTopic
512 toTopic := msg.Header.ToTopic
513 toDeviceID := msg.Header.ToDeviceId
514 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000515 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000516 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
517
518 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000519 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000520 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
521 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000522 {
mpagenko057889c2021-01-21 16:51:58 +0000523 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000524 }
mpagenkoaf801632020-07-03 10:00:42 +0000525 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
526 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000528 }
529 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
530 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000532
mpagenkoaf801632020-07-03 10:00:42 +0000533 }
534 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
535 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000537 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000538 default:
539 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 "msgType": msg.Header.Type, "device-id": dh.deviceID})
542 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000543 }
544 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000545}
546
mpagenkodff5dda2020-08-28 11:52:01 +0000547//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
549 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000550 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000552
mpagenko01e726e2020-10-23 09:45:29 +0000553 var retError error = nil
554 //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 +0000555 if apOfFlowChanges.ToRemove != nil {
556 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000557 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000558 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000559 "device-id": dh.deviceID})
560 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000561 continue
562 }
563 flowInPort := flow.GetInPort(flowItem)
564 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000565 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 +0000566 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
567 continue
568 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000569 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000570 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000571 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000572 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000573 continue
574 } else {
575 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530576 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000577 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
578 loUniPort = uniPort
579 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000581 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
582 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
583 flowInPort, dh.deviceID)
584 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000585 }
586 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000588 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000589 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000591 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000592 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000594 log.Fields{"device-id": dh.deviceID, "error": err})
595 retError = err
596 continue
597 //return err
598 } else { // if last setting succeeds, overwrite possibly previously set error
599 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000600 }
601 }
602 }
603 }
mpagenko01e726e2020-10-23 09:45:29 +0000604 if apOfFlowChanges.ToAdd != nil {
605 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
606 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000608 "device-id": dh.deviceID})
609 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
610 continue
611 }
612 flowInPort := flow.GetInPort(flowItem)
613 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 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 +0000615 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
616 continue
617 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
618 } else if flowInPort == dh.ponPortNumber {
619 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000621 "device-id": dh.deviceID, "inPort": flowInPort})
622 continue
623 } else {
624 // this is the relevant upstream flow
625 var loUniPort *onuUniPort
626 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
627 loUniPort = uniPort
628 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000630 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
631 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
632 flowInPort, dh.deviceID)
633 continue
634 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
635 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000636 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
637 // if not, we just throw some error here to have an indication about that, if we really need to support that
638 // then we would need to create some means to activate the internal stored flows
639 // after the device gets active automatically (and still with its dependency to the TechProfile)
640 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
641 // also abort for the other still possible flows here
642 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000644 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000645 return fmt.Errorf("improper device state on device %s", dh.deviceID)
646 }
647
mpagenko01e726e2020-10-23 09:45:29 +0000648 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000650 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
651 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000653 //try next flow after processing error
654 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000656 log.Fields{"device-id": dh.deviceID, "error": err})
657 retError = err
658 continue
659 //return err
660 } else { // if last setting succeeds, overwrite possibly previously set error
661 retError = nil
662 }
663 }
664 }
665 }
666 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000667}
668
Himani Chawla6d2ae152020-09-02 13:11:20 +0530669//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000670//following are the expected device states after this activity:
671//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
672// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
674 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000675
mpagenko900ee4b2020-10-12 11:56:34 +0000676 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000677 //note that disableDevice sequences in some 'ONU active' state may yield also
678 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000679 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000680 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000681 //disable-device shall be just a UNi/ONU-G related admin state setting
682 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000683
mpagenkofc4f56e2020-11-04 17:17:49 +0000684 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000685 // disable UNI ports/ONU
686 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
687 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000689 } else { //LockStateFSM already init
690 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000692 }
693 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000695 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000696 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000697 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
698 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000700 }
mpagenko01e726e2020-10-23 09:45:29 +0000701 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000702
703 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000705 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300706 }
707}
708
Himani Chawla6d2ae152020-09-02 13:11:20 +0530709//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000710func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
711 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000712
mpagenkofc4f56e2020-11-04 17:17:49 +0000713 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
714 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
715 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
716 // for real ONU's that should have nearly no influence
717 // Note that for real ONU's there is anyway a problematic situation with following sequence:
718 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
719 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
720 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
721 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
722
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000723 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000724 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000725 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000727 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000728 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000730 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300731}
732
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
734 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000735
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000737 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000739 return
740 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000742 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000744 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000746 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000747 dh.reconciling = false
748 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000749 }
Himani Chawla4d908332020-08-31 12:30:20 +0530750 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000751 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
752 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
753 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
754 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000756}
757
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
759 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000760
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000762 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000764 return
765 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000766 dh.pOnuTP.lockTpProcMutex()
767 defer dh.pOnuTP.unlockTpProcMutex()
768
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000769 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000771 log.Fields{"device-id": dh.deviceID})
772 dh.reconciling = false
773 return
774 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000775 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000776 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
777 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000779 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
780 dh.reconciling = false
781 return
782 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800783 for tpID := range uniData.PersTpPathMap {
784 // deadline context to ensure completion of background routines waited for
785 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
786 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000788
Girish Gowdra041dcb32020-11-16 16:54:30 -0800789 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
790 var wg sync.WaitGroup
791 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
793 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800794 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800796 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000797 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000798 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000800 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
801 dh.reconciling = false
802 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803 }
804}
805
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
807 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000810 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000812 return
813 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000814 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000816 log.Fields{"device-id": dh.deviceID})
817 dh.reconciling = false
818 return
819 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000820 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000821 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
822 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000824 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
825 dh.reconciling = false
826 return
827 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000828 var uniPort *onuUniPort
829 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000833 return
834 }
835 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000837 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000840 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
841 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000844 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000846 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000847 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000849 }
850 }
851 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000852 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
855 dh.reconciling = false
856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 }
858}
859
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
861 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 +0000862
863 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000864 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000865}
866
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
868 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000869
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000872 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000874 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000875 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 pDevEntry.lockOnuKVStoreMutex()
877 defer pDevEntry.unlockOnuKVStoreMutex()
878
879 // deadline context to ensure completion of background routines waited for
880 //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 +0530881 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000882 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000883
884 pDevEntry.resetKvProcessingErrorIndication()
885
886 var wg sync.WaitGroup
887 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
889 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000891 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000892 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000893}
894
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
896 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300897 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300900 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530902 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000903 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530904 return err
905 }
mpagenko01e726e2020-10-23 09:45:29 +0000906
907 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000909
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000911 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000912 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300913 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000914 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000915 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300916 return err
917 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300919 return err
920 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000921 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000922 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
923 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
924 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
925 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300926 return nil
927}
928
mpagenkoc8bba412021-01-15 15:38:44 +0000929//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
930func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
931 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
932 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000933 //return success to comfort the core processing during integration
934 return nil
935 // TODO!!: also verify error response behavior
936 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000937}
938
Himani Chawla6d2ae152020-09-02 13:11:20 +0530939// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000940// #####################################################################################
941
942// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530943// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000944
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
946 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 +0000947}
948
949// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000951
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000953 var err error
954
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000955 // populate what we know. rest comes later after mib sync
956 dh.device.Root = false
957 dh.device.Vendor = "OpenONU"
958 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000959 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000960 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000961
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000962 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000963
964 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000965 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
966 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530967 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000968 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000970 log.Fields{"device-id": dh.deviceID})
971 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000972
Himani Chawla4d908332020-08-31 12:30:20 +0530973 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000974 dh.ponPortNumber = dh.device.ParentPortNo
975
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000976 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
977 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
978 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000979 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000980 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530981 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000982
983 /*
984 self._pon = PonPort.create(self, self._pon_port_number)
985 self._pon.add_peer(self.parent_id, self._pon_port_number)
986 self.logger.debug('adding-pon-port-to-agent',
987 type=self._pon.get_port().type,
988 admin_state=self._pon.get_port().admin_state,
989 oper_status=self._pon.get_port().oper_status,
990 )
991 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000992 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000994 var ponPortNo uint32 = 1
995 if dh.ponPortNumber != 0 {
996 ponPortNo = dh.ponPortNumber
997 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000998
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000999 pPonPort := &voltha.Port{
1000 PortNo: ponPortNo,
1001 Label: fmt.Sprintf("pon-%d", ponPortNo),
1002 Type: voltha.Port_PON_ONU,
1003 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301004 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001005 PortNo: ponPortNo}}, // Peer port is parent's port number
1006 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001007 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1008 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001009 e.Cancel(err)
1010 return
1011 }
1012 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001014 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001016}
1017
1018// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001022 var err error
1023 /*
1024 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1025 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1026 return nil
1027 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1029 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001030 e.Cancel(err)
1031 return
1032 }
1033
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001034 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001035 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001036 // reconcilement will be continued after mib download is done
1037 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001038
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001039 /*
1040 ############################################################################
1041 # Setup Alarm handler
1042 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1043 device.serial_number)
1044 ############################################################################
1045 # Setup PM configuration for this device
1046 # Pass in ONU specific options
1047 kwargs = {
1048 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1049 'heartbeat': self.heartbeat,
1050 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1051 }
1052 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1053 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1054 self.logical_device_id, device.serial_number,
1055 grouped=True, freq_override=False, **kwargs)
1056 pm_config = self._pm_metrics.make_proto()
1057 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1058 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1059 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1060
1061 # Note, ONU ID and UNI intf set in add_uni_port method
1062 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1063 ani_ports=[self._pon])
1064
1065 # Code to Run OMCI Test Action
1066 kwargs_omci_test_action = {
1067 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1068 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1069 }
1070 serial_number = device.serial_number
1071 self._test_request = OmciTestRequest(self.core_proxy,
1072 self.omci_agent, self.device_id,
1073 AniG, serial_number,
1074 self.logical_device_id,
1075 exclusive=False,
1076 **kwargs_omci_test_action)
1077
1078 self.enabled = True
1079 else:
1080 self.logger.info('onu-already-activated')
1081 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001082
dbainbri4d3a0dc2020-12-02 00:33:42 +00001083 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001084}
1085
1086// doStateConnected get the device info and update to voltha core
1087// for comparison of the original method (not that easy to uncomment): compare here:
1088// voltha-openolt-adapter/adaptercore/device_handler.go
1089// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001090func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001091
dbainbri4d3a0dc2020-12-02 00:33:42 +00001092 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301093 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001094 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001095 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001096}
1097
1098// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001100
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301102 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001103 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001105
1106 /*
1107 // Synchronous call to update device state - this method is run in its own go routine
1108 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1109 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001110 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 +00001111 return err
1112 }
1113 return nil
1114 */
1115}
1116
1117// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121 var err error
1122
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001123 device := dh.device
1124 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001127 e.Cancel(err)
1128 return
1129 }
1130
1131 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 /*
1134 // Update the all ports state on that device to disable
1135 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001136 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001137 return er
1138 }
1139
1140 //Update the device oper state and connection status
1141 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1142 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1143 dh.device = cloned
1144
1145 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001146 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147 return er
1148 }
1149
1150 //get the child device for the parent device
1151 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1152 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001153 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001154 return err
1155 }
1156 for _, onuDevice := range onuDevices.Items {
1157
1158 // Update onu state as down in onu adapter
1159 onuInd := oop.OnuIndication{}
1160 onuInd.OperState = "down"
1161 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1162 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1163 if er != nil {
1164 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001165 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001166 //Do not return here and continue to process other ONUs
1167 }
1168 }
1169 // * Discovered ONUs entries need to be cleared , since after OLT
1170 // is up, it starts sending discovery indications again* /
1171 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001172 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001173 return nil
1174 */
Himani Chawla4d908332020-08-31 12:30:20 +05301175 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001178}
1179
Himani Chawla6d2ae152020-09-02 13:11:20 +05301180// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001181// #################################################################################
1182
1183// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301184// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001185
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001186//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001187func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001188 dh.lockDevice.RLock()
1189 pOnuDeviceEntry := dh.pOnuOmciDevice
1190 if aWait && pOnuDeviceEntry == nil {
1191 //keep the read sema short to allow for subsequent write
1192 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001194 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1195 // so it might be needed to wait here for that event with some timeout
1196 select {
1197 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001199 return nil
1200 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001201 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001202 // if written now, we can return the written value without sema
1203 return dh.pOnuOmciDevice
1204 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001205 }
mpagenko3af1f032020-06-10 08:53:41 +00001206 dh.lockDevice.RUnlock()
1207 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001208}
1209
Himani Chawla6d2ae152020-09-02 13:11:20 +05301210//setOnuDeviceEntry sets the ONU device entry within the handler
1211func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001212 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001213 dh.lockDevice.Lock()
1214 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001215 dh.pOnuOmciDevice = apDeviceEntry
1216 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001217 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001218}
1219
Himani Chawla6d2ae152020-09-02 13:11:20 +05301220//addOnuDeviceEntry creates a new ONU device or returns the existing
1221func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001223
dbainbri4d3a0dc2020-12-02 00:33:42 +00001224 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001225 if deviceEntry == nil {
1226 /* costum_me_map in python code seems always to be None,
1227 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1228 /* also no 'clock' argument - usage open ...*/
1229 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001230 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001231 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001232 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001233 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001234 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001235 // fire deviceEntry ready event to spread to possibly waiting processing
1236 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001238 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001239 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001240 }
1241 // might be updated with some error handling !!!
1242 return nil
1243}
1244
dbainbri4d3a0dc2020-12-02 00:33:42 +00001245func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1246 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001247 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1248
1249 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001250
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001252 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001254 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1255 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001256 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257 if err := dh.storePersistentData(ctx); err != nil {
1258 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001259 log.Fields{"device-id": dh.deviceID, "err": err})
1260 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001261 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001262 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001264 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1265 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001267 }
1268 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001270 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001271
1272 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 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 +00001274 log.Fields{"device-id": dh.deviceID})
1275 dh.reconciling = false
1276 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001277 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001278 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1279 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1280 // 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 +00001281 // 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 +00001282 // so let's just try to keep it simple ...
1283 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001285 if err != nil || device == nil {
1286 //TODO: needs to handle error scenarios
1287 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1288 return errors.New("Voltha Device not found")
1289 }
1290 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001291
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001293 return err
mpagenko3af1f032020-06-10 08:53:41 +00001294 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001295
dbainbri4d3a0dc2020-12-02 00:33:42 +00001296 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001297
1298 /* this might be a good time for Omci Verify message? */
1299 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001300 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001301 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001302 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001304
1305 /* give the handler some time here to wait for the OMCi verification result
1306 after Timeout start and try MibUpload FSM anyway
1307 (to prevent stopping on just not supported OMCI verification from ONU) */
1308 select {
1309 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001310 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001311 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001313 }
1314
1315 /* In py code it looks earlier (on activate ..)
1316 # Code to Run OMCI Test Action
1317 kwargs_omci_test_action = {
1318 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1319 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1320 }
1321 serial_number = device.serial_number
1322 self._test_request = OmciTestRequest(self.core_proxy,
1323 self.omci_agent, self.device_id,
1324 AniG, serial_number,
1325 self.logical_device_id,
1326 exclusive=False,
1327 **kwargs_omci_test_action)
1328 ...
1329 # Start test requests after a brief pause
1330 if not self._test_request_started:
1331 self._test_request_started = True
1332 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1333 reactor.callLater(tststart, self._test_request.start_collector)
1334
1335 */
1336 /* which is then: in omci_test_request.py : */
1337 /*
1338 def start_collector(self, callback=None):
1339 """
1340 Start the collection loop for an adapter if the frequency > 0
1341
1342 :param callback: (callable) Function to call to collect PM data
1343 """
1344 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1345 if callback is None:
1346 callback = self.perform_test_omci
1347
1348 if self.lc is None:
1349 self.lc = LoopingCall(callback)
1350
1351 if self.default_freq > 0:
1352 self.lc.start(interval=self.default_freq / 10)
1353
1354 def perform_test_omci(self):
1355 """
1356 Perform the initial test request
1357 """
1358 ani_g_entities = self._device.configuration.ani_g_entities
1359 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1360 is not None else None
1361 self._entity_id = ani_g_entities_ids[0]
1362 self.logger.info('perform-test', entity_class=self._entity_class,
1363 entity_id=self._entity_id)
1364 try:
1365 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1366 result = yield self._device.omci_cc.send(frame)
1367 if not result.fields['omci_message'].fields['success_code']:
1368 self.logger.info('Self-Test Submitted Successfully',
1369 code=result.fields[
1370 'omci_message'].fields['success_code'])
1371 else:
1372 raise TestFailure('Test Failure: {}'.format(
1373 result.fields['omci_message'].fields['success_code']))
1374 except TimeoutError as e:
1375 self.deferred.errback(failure.Failure(e))
1376
1377 except Exception as e:
1378 self.logger.exception('perform-test-Error', e=e,
1379 class_id=self._entity_class,
1380 entity_id=self._entity_id)
1381 self.deferred.errback(failure.Failure(e))
1382
1383 */
1384
1385 // PM related heartbeat??? !!!TODO....
1386 //self._heartbeat.enabled = True
1387
mpagenko1cc3cb42020-07-27 15:24:38 +00001388 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1389 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1390 * 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 +05301391 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001392 */
1393 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001394 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001395 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001396 if pMibUlFsm.Is(ulStDisabled) {
1397 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001398 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 +00001399 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301400 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301402 //Determine ONU status and start/re-start MIB Synchronization tasks
1403 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001404 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301405 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001406 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 +00001407 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001408 }
Himani Chawla4d908332020-08-31 12:30:20 +05301409 } else {
1410 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411 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 +00001412 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301413 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001414 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001415 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001416 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001417 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001418 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001419 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001420 }
1421 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001423 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001424 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001425
1426 // Start PM collector routine
1427 go dh.startCollector(ctx)
1428
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001429 return nil
1430}
1431
dbainbri4d3a0dc2020-12-02 00:33:42 +00001432func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001433 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001434 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001435 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001437
mpagenko900ee4b2020-10-12 11:56:34 +00001438 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1439 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1440 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001441 if err := dh.resetFsms(ctx); err != nil {
1442 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001443 log.Fields{"device-id": dh.deviceID, "error": err})
1444 // abort: system behavior is just unstable ...
1445 return err
1446 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001447 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 _ = 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 +00001449
1450 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1451 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1452 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001453 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001454 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001456 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001457 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001458 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001459
1460 //TODO!!! remove existing traffic profiles
1461 /* from py code, if TP's exist, remove them - not yet implemented
1462 self._tp = dict()
1463 # Let TP download happen again
1464 for uni_id in self._tp_service_specific_task:
1465 self._tp_service_specific_task[uni_id].clear()
1466 for uni_id in self._tech_profile_download_done:
1467 self._tech_profile_download_done[uni_id].clear()
1468 */
1469
dbainbri4d3a0dc2020-12-02 00:33:42 +00001470 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001471
mpagenkofc4f56e2020-11-04 17:17:49 +00001472 dh.ReadyForSpecificOmciConfig = false
1473
dbainbri4d3a0dc2020-12-02 00:33:42 +00001474 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001475 // abort: system behavior is just unstable ...
1476 return err
1477 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001478 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001479 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001480 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001481 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001482 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001484 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001485 // abort: system behavior is just unstable ...
1486 return err
1487 }
1488 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001490 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001491 return nil
1492}
1493
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001495 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1496 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1497 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1498 // and using the stop/reset event should never harm
1499
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001501 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001503 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1504 }
mpagenko900ee4b2020-10-12 11:56:34 +00001505 //the MibSync FSM might be active all the ONU-active time,
1506 // hence it must be stopped unconditionally
1507 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1508 if pMibUlFsm != nil {
1509 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1510 }
1511 //MibDownload may run
1512 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1513 if pMibDlFsm != nil {
1514 _ = pMibDlFsm.Event(dlEvReset)
1515 }
1516 //port lock/unlock FSM's may be active
1517 if dh.pUnlockStateFsm != nil {
1518 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1519 }
1520 if dh.pLockStateFsm != nil {
1521 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1522 }
1523 //techProfile related PonAniConfigFsm FSM may be active
1524 if dh.pOnuTP != nil {
1525 // should always be the case here
1526 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1527 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001528 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1529 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1530 }
mpagenko900ee4b2020-10-12 11:56:34 +00001531 }
1532 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001533 // reset the possibly existing VlanConfigFsm
1534 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1535 //VlanFilterFsm exists and was already started
1536 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1537 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001538 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001539 // no need to remove specific data
1540 pVlanFilterFsm.RequestClearPersistency(false)
1541 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001542 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1543 }
1544 }
1545 }
1546 }
Girish Gowdraaf0ad632021-01-27 13:00:01 -08001547
1548 // Stop collector routine
Girish Gowdrae09a6202021-01-12 18:10:59 -08001549 dh.stopCollector <- true
1550
mpagenko900ee4b2020-10-12 11:56:34 +00001551 return nil
1552}
1553
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1555 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 +05301556
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1558 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001559 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001561 return
1562 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001563 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001564 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1565 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1566 for _, mgmtEntityID := range pptpInstKeys {
1567 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1568 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301570 i++
1571 }
1572 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301574 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001575 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1576 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301577 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001578 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301579 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001580 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301581 i++
1582 }
1583 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301585 }
1586 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301588 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001589 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1590 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1591 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1592 * disable/enable toggling here to allow traffic
1593 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1594 * like the py comment says:
1595 * # start by locking all the unis till mib sync and initial mib is downloaded
1596 * # this way we can capture the port down/up events when we are ready
1597 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301598
mpagenkoa40e99a2020-11-17 13:50:39 +00001599 // Init Uni Ports to Admin locked state
1600 // *** should generate UniLockStateDone event *****
1601 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001603 } else { //LockStateFSM already init
1604 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001606 }
1607}
1608
dbainbri4d3a0dc2020-12-02 00:33:42 +00001609func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1610 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301611 /* Mib download procedure -
1612 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1613 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001615 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001617 return
1618 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301619 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1620 if pMibDlFsm != nil {
1621 if pMibDlFsm.Is(dlStDisabled) {
1622 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 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 +05301624 // maybe try a FSM reset and then again ... - TODO!!!
1625 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301627 // maybe use more specific states here for the specific download steps ...
1628 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301630 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301632 //Begin MIB data download (running autonomously)
1633 }
1634 }
1635 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001637 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301638 // maybe try a FSM reset and then again ... - TODO!!!
1639 }
1640 /***** Mib download started */
1641 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301643 }
1644}
1645
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1647 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301648 //initiate DevStateUpdate
1649 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001651 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301653 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1654 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301658 }
1659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001661 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001663 return
1664 }
1665 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 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 +00001667 log.Fields{"device-id": dh.deviceID})
1668 dh.reconciling = false
1669 return
1670 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001671 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301672 log.Fields{"device-id": dh.deviceID})
1673 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001675 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 // *** should generate UniUnlockStateDone event *****
1677 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301679 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301680 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301682 }
1683}
1684
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1686 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301687
1688 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301690 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1692 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001693 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001695 return
1696 }
1697 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 if err := dh.storePersistentData(ctx); err != nil {
1699 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001700 log.Fields{"device-id": dh.deviceID, "err": err})
1701 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301702 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 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 +05301704 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001706 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301707 }
1708}
1709
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1711 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001712 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001714 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1715 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001717 }
1718
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001720 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001721 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001722
1723 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001725
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001727 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001728 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001729 return
1730 }
1731 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 if err := dh.storePersistentData(ctx); err != nil {
1733 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001734 log.Fields{"device-id": dh.deviceID, "err": err})
1735 }
mpagenko900ee4b2020-10-12 11:56:34 +00001736}
1737
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1739 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001740 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001742 voltha.OperStatus_ACTIVE); err != nil {
1743 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001745 }
1746
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001748 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001749 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001751
1752 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001754
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001756 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001758 return
1759 }
1760 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001761 if err := dh.storePersistentData(ctx); err != nil {
1762 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001763 log.Fields{"device-id": dh.deviceID, "err": err})
1764 }
mpagenko900ee4b2020-10-12 11:56:34 +00001765}
1766
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001768 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001770 // attention: the device reason update is done based on ONU-UNI-Port related activity
1771 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001772 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001773 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301775 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001776 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001778 }
1779 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001781 // attention: the device reason update is done based on ONU-UNI-Port related activity
1782 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001783 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001784 // 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 +00001785 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001786 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001787 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301788}
1789
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1791 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001792 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301793 // attention: the device reason update is done based on ONU-UNI-Port related activity
1794 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301795
mpagenkofc4f56e2020-11-04 17:17:49 +00001796 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001797 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001798 // which may be the case from some previous actvity on another UNI Port of the ONU
1799 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001801 // request MDS-value for test and logging purposes
1802 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001803 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001805 }
1806 }
1807 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001808 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001809 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001811 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301812 }
1813}
1814
Himani Chawla6d2ae152020-09-02 13:11:20 +05301815//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301817 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001818 case MibDatabaseSync:
1819 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001821 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001822 case UniLockStateDone:
1823 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001825 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001826 case MibDownloadDone:
1827 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001829 }
1830 case UniUnlockStateDone:
1831 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001833 }
mpagenko900ee4b2020-10-12 11:56:34 +00001834 case UniEnableStateDone:
1835 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001837 }
1838 case UniDisableStateDone:
1839 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001841 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001842 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001843 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001845 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001846 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001847 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001849 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001850 default:
1851 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001852 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001853 }
1854 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001855}
1856
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001858 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301860 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001861 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001863 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301864 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001866 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001868 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001869 //store UniPort with the System-PortNumber key
1870 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001871 if !dh.reconciling {
1872 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1874 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001875 } //error logging already within UniPort method
1876 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001878 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001879 }
1880 }
1881}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001882
mpagenko3af1f032020-06-10 08:53:41 +00001883// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001885 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301886 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001887 // with following remark:
1888 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1889 // # load on the core
1890
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001891 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001892
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001893 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001894 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301895 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301897 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001898 if !dh.reconciling {
1899 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 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 +00001901 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001902 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001903 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001904 }
mpagenko3af1f032020-06-10 08:53:41 +00001905 }
1906 }
1907}
1908
1909// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001911 // compare enableUniPortStateUpdate() above
1912 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1913 for uniNo, uniPort := range dh.uniEntityMap {
1914 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301915 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301917 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001918 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919 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 +00001920 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001921 }
1922}
1923
1924// ONU_Active/Inactive announcement on system KAFKA bus
1925// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001926func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001927 var de voltha.DeviceEvent
1928 eventContext := make(map[string]string)
1929 //Populating event context
1930 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001932 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301934 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001935 }
1936 oltSerialNumber := parentDevice.SerialNumber
1937
1938 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1939 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1940 eventContext["serial-number"] = dh.device.SerialNumber
1941 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301942 eventContext["device_id"] = aDeviceID
1943 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001945 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001946
1947 /* Populating device event body */
1948 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301949 de.ResourceId = aDeviceID
1950 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001951 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1952 de.Description = fmt.Sprintf("%s Event - %s - %s",
1953 cEventObjectType, cOnuActivatedEvent, "Raised")
1954 } else {
1955 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1956 de.Description = fmt.Sprintf("%s Event - %s - %s",
1957 cEventObjectType, cOnuActivatedEvent, "Cleared")
1958 }
1959 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1961 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301962 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001963 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301965 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001966}
1967
Himani Chawla4d908332020-08-31 12:30:20 +05301968// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001970 chLSFsm := make(chan Message, 2048)
1971 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301972 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001974 sFsmName = "LockStateFSM"
1975 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001977 sFsmName = "UnLockStateFSM"
1978 }
mpagenko3af1f032020-06-10 08:53:41 +00001979
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001981 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001983 return
1984 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001985 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001986 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001987 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301988 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001989 dh.pLockStateFsm = pLSFsm
1990 } else {
1991 dh.pUnlockStateFsm = pLSFsm
1992 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001994 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001996 }
1997}
1998
1999// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002001 /* Uni Port lock/unlock procedure -
2002 ***** should run via 'adminDone' state and generate the argument requested event *****
2003 */
2004 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302005 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002006 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2007 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2008 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002009 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302010 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002011 }
2012 } else {
2013 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2014 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2015 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002016 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302017 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002018 }
2019 }
2020 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002021 if pLSStatemachine.Is(uniStDisabled) {
2022 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002024 // maybe try a FSM reset and then again ... - TODO!!!
2025 } else {
2026 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002028 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002029 }
2030 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002032 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002033 // maybe try a FSM reset and then again ... - TODO!!!
2034 }
2035 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002037 // maybe try a FSM reset and then again ... - TODO!!!
2038 }
2039}
2040
Himani Chawla6d2ae152020-09-02 13:11:20 +05302041//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002043
2044 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002045 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002046 kvbackend := &db.Backend{
2047 Client: dh.pOpenOnuAc.kvClient,
2048 StoreType: dh.pOpenOnuAc.KVStoreType,
2049 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002050 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002051 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2052 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002053
mpagenkoaf801632020-07-03 10:00:42 +00002054 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002055}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302057 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002058
mpagenkodff5dda2020-08-28 11:52:01 +00002059 for _, field := range flow.GetOfbFields(apFlowItem) {
2060 switch field.Type {
2061 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2062 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002064 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2065 }
mpagenko01e726e2020-10-23 09:45:29 +00002066 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002067 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2068 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302069 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002070 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302071 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2072 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002073 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2074 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002075 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2076 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302077 return
mpagenkodff5dda2020-08-28 11:52:01 +00002078 }
2079 }
mpagenko01e726e2020-10-23 09:45:29 +00002080 */
mpagenkodff5dda2020-08-28 11:52:01 +00002081 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2082 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302083 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002084 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302085 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002086 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302087 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002088 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302090 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002091 }
2092 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2093 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302094 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002095 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002096 "PCP": loAddPcp})
2097 }
2098 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2099 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002100 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002101 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2102 }
2103 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2104 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002106 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2107 }
2108 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2109 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002110 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002111 "IPv4-DST": field.GetIpv4Dst()})
2112 }
2113 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2114 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002115 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002116 "IPv4-SRC": field.GetIpv4Src()})
2117 }
2118 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2119 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002121 "Metadata": field.GetTableMetadata()})
2122 }
2123 /*
2124 default:
2125 {
2126 //all other entires ignored
2127 }
2128 */
2129 }
2130 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302131}
mpagenkodff5dda2020-08-28 11:52:01 +00002132
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002134 for _, action := range flow.GetActions(apFlowItem) {
2135 switch action.Type {
2136 /* not used:
2137 case of.OfpActionType_OFPAT_OUTPUT:
2138 {
mpagenko01e726e2020-10-23 09:45:29 +00002139 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002140 "Output": action.GetOutput()})
2141 }
2142 */
2143 case of.OfpActionType_OFPAT_PUSH_VLAN:
2144 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002146 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2147 }
2148 case of.OfpActionType_OFPAT_SET_FIELD:
2149 {
2150 pActionSetField := action.GetSetField()
2151 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002153 "OxcmClass": pActionSetField.Field.OxmClass})
2154 }
2155 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302158 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002159 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302160 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302162 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002163 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002165 "Type": pActionSetField.Field.GetOfbField().Type})
2166 }
2167 }
2168 /*
2169 default:
2170 {
2171 //all other entires ignored
2172 }
2173 */
2174 }
2175 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302176}
2177
2178//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302180 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2181 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2182 var loAddPcp, loSetPcp uint8
2183 var loIPProto uint32
2184 /* the TechProfileId is part of the flow Metadata - compare also comment within
2185 * OLT-Adapter:openolt_flowmgr.go
2186 * Metadata 8 bytes:
2187 * Most Significant 2 Bytes = Inner VLAN
2188 * Next 2 Bytes = Tech Profile ID(TPID)
2189 * Least Significant 4 Bytes = Port ID
2190 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2191 * subscriber related flows.
2192 */
2193
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302195 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302197 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002198 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302199 }
mpagenko551a4d42020-12-08 18:09:20 +00002200 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002201 loCookie := apFlowItem.GetCookie()
2202 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002204 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302205
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002207 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 if loIPProto == 2 {
2209 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2210 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002211 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2212 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302213 return nil
2214 }
mpagenko01e726e2020-10-23 09:45:29 +00002215 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002217
2218 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002220 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2221 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2222 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2223 //TODO!!: Use DeviceId within the error response to rwCore
2224 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002225 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002226 }
2227 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002229 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2230 } else {
2231 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2232 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2233 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302234 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002235 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002237 }
mpagenko9a304ea2020-12-16 15:54:01 +00002238
2239 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2240 dh.lockVlanConfig.Lock()
2241 defer dh.lockVlanConfig.Unlock()
2242 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302243 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002245 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002246 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002248 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002249}
2250
2251//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002253 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2254 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2255 //no extra check is done on the rule parameters
2256 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2257 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2258 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2259 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002260 // - 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 +00002261 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002263
2264 /* TT related temporary workaround - should not be needed anymore
2265 for _, field := range flow.GetOfbFields(apFlowItem) {
2266 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2267 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002268 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002269 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2270 if loIPProto == 2 {
2271 // 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 +00002272 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002273 log.Fields{"device-id": dh.deviceID})
2274 return nil
2275 }
2276 }
2277 } //for all OfbFields
2278 */
2279
mpagenko9a304ea2020-12-16 15:54:01 +00002280 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2281 dh.lockVlanConfig.Lock()
2282 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002283 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002285 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002287 log.Fields{"device-id": dh.deviceID})
2288 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002289 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002291
mpagenko01e726e2020-10-23 09:45:29 +00002292 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002293}
2294
Himani Chawla26e555c2020-08-31 12:30:20 +05302295// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002296// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002297func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002298 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002299 chVlanFilterFsm := make(chan Message, 2048)
2300
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002302 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002303 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302304 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002305 }
2306
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002308 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2309 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002310 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302311 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002312 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2313 if pVlanFilterStatemachine != nil {
2314 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2315 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302317 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002318 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302319 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302321 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2322 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002323 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002325 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302326 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002327 }
2328 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002330 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302331 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002332 }
2333 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002335 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302336 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002337 }
2338 return nil
2339}
2340
mpagenkofc4f56e2020-11-04 17:17:49 +00002341//VerifyVlanConfigRequest checks on existence of a given uniPort
2342// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002343func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002344 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2345 var pCurrentUniPort *onuUniPort
2346 for _, uniPort := range dh.uniEntityMap {
2347 // only if this port is validated for operState transfer
2348 if uniPort.uniID == uint8(aUniID) {
2349 pCurrentUniPort = uniPort
2350 break //found - end search loop
2351 }
2352 }
2353 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002355 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2356 return
2357 }
mpagenko551a4d42020-12-08 18:09:20 +00002358 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002359}
2360
mpagenkodff5dda2020-08-28 11:52:01 +00002361//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002362func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002363 //TODO!! verify and start pending flow configuration
2364 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2365 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302366 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002367 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2368 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2369 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002370 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2371 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2372 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2373 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2374 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2375 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2376 } else {
2377 /***** UniVlanConfigFsm continued */
2378 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2379 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2380 "UniPort": apUniPort.portNo})
2381 }
2382 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2383 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2384 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2385 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2386 } else {
2387 /***** UniVlanConfigFsm continued */
2388 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2389 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2390 "UniPort": apUniPort.portNo})
2391 }
mpagenkodff5dda2020-08-28 11:52:01 +00002392 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002393 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2394 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002395 "UniPort": apUniPort.portNo})
2396 }
2397 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002398 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2399 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2400 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002401 }
2402 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002404 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002405 }
mpagenkodff5dda2020-08-28 11:52:01 +00002406 } // else: nothing to do
2407}
2408
2409//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2410// 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 +00002411func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2412 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002413 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2414 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302415 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002416}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002417
Girish Gowdra26a40922021-01-29 17:14:34 -08002418//ProcessPendingTpDelete processes any pending TP delete (if available)
2419func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2420 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2421 if apUniPort == nil {
2422 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2423 return
2424 }
2425 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2426 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2427 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2428 if pAniConfigStatemachine != nil {
2429 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2430 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2431 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2432 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2433 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2434 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2435 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2436 return
2437 }
2438 } else {
2439 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2440 return
2441 }
2442 }
2443 return
2444 }
2445}
2446
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002447//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2448//available for potential reconcilement
2449
dbainbri4d3a0dc2020-12-02 00:33:42 +00002450func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002451
2452 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002454 return nil
2455 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002456 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002457
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002459 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002461 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2462 }
2463 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2464
2465 pDevEntry.lockOnuKVStoreMutex()
2466 defer pDevEntry.unlockOnuKVStoreMutex()
2467
2468 // deadline context to ensure completion of background routines waited for
2469 //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 +05302470 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002471 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2472
2473 pDevEntry.resetKvProcessingErrorIndication()
2474 var wg sync.WaitGroup
2475 wg.Add(1) // for the 1 go routine to finish
2476
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2478 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002479
2480 return pDevEntry.getKvProcessingErrorIndication()
2481}
2482
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002484 defer cancel() //ensure termination of context (may be pro forma)
2485 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002486 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002487 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002488}
2489
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002491
2492 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002493 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002494 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2496 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002497 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002498 return err
2499 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002501 return nil
2502 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002503 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002504 return nil
2505}
2506
dbainbri4d3a0dc2020-12-02 00:33:42 +00002507func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2508 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002509 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002510 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002511 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2512 }
2513 pDevEntry.lockOnuKVStoreMutex()
2514 defer pDevEntry.unlockOnuKVStoreMutex()
2515
2516 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2517 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2518
2519 pDevEntry.resetKvProcessingErrorIndication()
2520 var wg sync.WaitGroup
2521 wg.Add(1) // for the 1 go routine to finish
2522
2523 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002525
2526 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002527 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002528 return err
2529 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002530 return nil
2531}
2532
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002533func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2534 var errStr string = ""
2535 for _, err := range errS {
2536 if err != nil {
2537 errStr = errStr + err.Error() + " "
2538 }
2539 }
2540 if errStr != "" {
2541 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2542 }
2543 return nil
2544}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002545
2546// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2547func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2548 dh.lockDevice.RLock()
2549 defer dh.lockDevice.RUnlock()
2550 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2551 return uniPort.entityID, nil
2552 }
2553 return 0, errors.New("error-fetching-uni-port")
2554}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002555
2556// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002557func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2558 var errorsList []error
2559 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 -08002560
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002561 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2562 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2563 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2564
2565 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2566 // successfully.
2567 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2568 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2569 if len(errorsList) > 0 {
2570 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2571 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002572 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002573 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2574 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002575}
2576
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002577func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2578 var err error
2579 var errorsList []error
2580 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2581
2582 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2583 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2584 errorsList = append(errorsList, err)
2585 }
2586 }
2587
2588 return errorsList
2589}
2590
2591func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2592 var err error
2593 var errorsList []error
2594 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2595 // Check if group metric related config is updated
2596 for _, v := range pmConfigs.Groups {
2597 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2598 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2599 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2600
2601 if ok && m.frequency != v.GroupFreq {
2602 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2603 errorsList = append(errorsList, err)
2604 }
2605 }
2606 if ok && m.enabled != v.Enabled {
2607 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2608 errorsList = append(errorsList, err)
2609 }
2610 }
2611 }
2612 return errorsList
2613}
2614
2615func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2616 var err error
2617 var errorsList []error
2618 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2619 // Check if standalone metric related config is updated
2620 for _, v := range pmConfigs.Metrics {
2621 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002622 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002623 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2624
2625 if ok && m.frequency != v.SampleFreq {
2626 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2627 errorsList = append(errorsList, err)
2628 }
2629 }
2630 if ok && m.enabled != v.Enabled {
2631 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2632 errorsList = append(errorsList, err)
2633 }
2634 }
2635 }
2636 return errorsList
2637}
2638
2639// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002640func (dh *deviceHandler) startCollector(ctx context.Context) {
2641 logger.Debugf(ctx, "startingCollector")
2642
2643 // Start routine to process OMCI GET Responses
2644 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002645 // Initialize the next metric collection time.
2646 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2647 // reset like onu rebooted.
2648 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002649 for {
2650 select {
2651 case <-dh.stopCollector:
2652 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2653 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2654 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002655 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2656 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2657 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2658 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2659 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002660 // Update the next metric collection time.
2661 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002662 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002663 } else {
2664 if dh.pmConfigs.Grouped { // metrics are managed as a group
2665 // parse through the group and standalone metrics to see it is time to collect their metrics
2666 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002667
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002668 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2669 // If the group is enabled AND (current time is equal to OR after nextCollectionInterval, collect the group metric)
2670 if g.enabled && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
2671 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2672 }
2673 }
2674 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2675 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2676 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2677 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2678 }
2679 }
2680 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2681
2682 // parse through the group and update the next metric collection time
2683 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2684 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2685 // If group enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2686 if g.enabled && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
2687 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2688 }
2689 }
2690 // parse through the standalone metrics and update the next metric collection time
2691 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2692 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2693 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2694 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2695 }
2696 }
2697 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2698 } /* else { // metrics are not managed as a group
2699 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2700 } */
2701 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002702 }
2703 }
2704}
kesavandfdf77632021-01-26 23:40:33 -05002705
2706func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2707
2708 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2709 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2710}