blob: 7405f201ee36057645a656c6f48463902978e056 [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"
39 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt80129db2020-11-23 10:49:32 +000094const (
95 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +000096 drUnset = 0
97 drActivatingOnu = 1
98 drStartingOpenomci = 2
99 drDiscoveryMibsyncComplete = 3
100 drInitialMibDownloaded = 4
101 drTechProfileConfigDownloadSuccess = 5
102 drOmciFlowsPushed = 6
103 drOmciAdminLock = 7
104 drOnuReenabled = 8
105 drStoppingOpenomci = 9
106 drRebooting = 10
107 drOmciFlowsDeleted = 11
108 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000109)
110
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000111var deviceReasonMap = map[uint8]string{
112 drUnset: "unset",
113 drActivatingOnu: "activating-onu",
114 drStartingOpenomci: "starting-openomci",
115 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
116 drInitialMibDownloaded: "initial-mib-downloaded",
117 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
118 drOmciFlowsPushed: "omci-flows-pushed",
119 drOmciAdminLock: "omci-admin-lock",
120 drOnuReenabled: "onu-reenabled",
121 drStoppingOpenomci: "stopping-openomci",
122 drRebooting: "rebooting",
123 drOmciFlowsDeleted: "omci-flows-deleted",
124 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
125}
126
Himani Chawla6d2ae152020-09-02 13:11:20 +0530127//deviceHandler will interact with the ONU ? device.
128type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000129 deviceID string
130 DeviceType string
131 adminState string
132 device *voltha.Device
133 logicalDeviceID string
134 ProxyAddressID string
135 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530136 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000137 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000138
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000139 coreProxy adapterif.CoreProxy
140 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530141 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000142
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800143 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800144
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000145 pOpenOnuAc *OpenONUAC
146 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530147 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000148 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000149 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800151 pOnuMetricsMgr *onuMetricsManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152 exitChannel chan int
153 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000154 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000155 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530156 pLockStateFsm *lockStateFsm
157 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000158
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000159 //flowMgr *OpenOltFlowMgr
160 //eventMgr *OpenOltEventMgr
161 //resourceMgr *rsrcMgr.OpenOltResourceMgr
162
163 //discOnus sync.Map
164 //onus sync.Map
165 //portStats *OpenOltStatisticsMgr
mpagenkofc4f56e2020-11-04 17:17:49 +0000166 stopCollector chan bool
167 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000168 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000169 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000170 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
171 reconciling bool
172 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173}
174
Himani Chawla6d2ae152020-09-02 13:11:20 +0530175//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530176func 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 +0530177 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178 dh.coreProxy = cp
179 dh.AdapterProxy = ap
180 dh.EventProxy = ep
181 cloned := (proto.Clone(device)).(*voltha.Device)
182 dh.deviceID = cloned.Id
183 dh.DeviceType = cloned.Type
184 dh.adminState = "up"
185 dh.device = cloned
186 dh.pOpenOnuAc = adapter
187 dh.exitChannel = make(chan int, 1)
188 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000189 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 dh.stopCollector = make(chan bool, 2)
191 dh.stopHeartbeatCheck = make(chan bool, 2)
192 //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 +0000193 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530194 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000195 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000196 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000197 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000198 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000199
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800200 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
201 dh.pmConfigs = cloned.PmConfigs
202 } /* else {
203 // will be populated when onu_metrics_mananger is initialized.
204 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800205
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 // Device related state machine
207 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000208 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000209 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000210 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
211 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
212 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
213 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
214 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 },
216 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000217 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
218 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
219 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
220 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
221 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
222 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
223 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
224 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225 },
226 )
mpagenkoaf801632020-07-03 10:00:42 +0000227
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228 return &dh
229}
230
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231// start save the device to the data model
232func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000233 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000234 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000235 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236}
237
Himani Chawla4d908332020-08-31 12:30:20 +0530238/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000241 logger.Debug("stopping-device-handler")
242 dh.exitChannel <- 1
243}
Himani Chawla4d908332020-08-31 12:30:20 +0530244*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245
246// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530247// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248
Himani Chawla6d2ae152020-09-02 13:11:20 +0530249//adoptOrReconcileDevice adopts the OLT device
250func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000251 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252
dbainbri4d3a0dc2020-12-02 00:33:42 +0000253 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000254 if dh.pDeviceStateFsm.Is(devStNull) {
255 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000256 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000258 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800259 if device.PmConfigs == nil { // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
260 // Now, set the initial PM configuration for that device
261 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
262 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
263 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800264 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000265 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000266 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267 }
268
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269}
270
mpagenko057889c2021-01-21 16:51:58 +0000271func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530272 msgBody := msg.GetBody()
273 omciMsg := &ic.InterAdapterOmciMessage{}
274 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000275 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530276 "device-id": dh.deviceID, "error": err})
277 return err
278 }
279
280 //assuming omci message content is hex coded!
281 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000282 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530283 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
284 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530286 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000287 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000288 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000289 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 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 +0530291 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000292 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000293 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530294}
295
Himani Chawla6d2ae152020-09-02 13:11:20 +0530296func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530298 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000299
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000301
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000303 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000305 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
306 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530307 if dh.pOnuTP == nil {
308 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000309 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530310 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000311 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530312 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000313 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000314 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000315 "device-state": deviceReasonMap[dh.deviceReason]})
316 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530317 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000318 //previous state test here was just this one, now extended for more states to reject the SetRequest:
319 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
320 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530321
322 msgBody := msg.GetBody()
323 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
324 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000325 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530326 "device-id": dh.deviceID, "error": err})
327 return err
328 }
329
330 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000331 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
332 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530333 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000334 defer dh.pOnuTP.unlockTpProcMutex()
335 pDevEntry.lockOnuKVStoreMutex()
336 defer pDevEntry.unlockOnuKVStoreMutex()
337
338 if techProfMsg.UniId > 255 {
339 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
340 techProfMsg.UniId, dh.deviceID))
341 }
342 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800343 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
344 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800346 return err
347 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000348
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 // if there has been some change for some uni TechProfilePath
351 //in order to allow concurrent calls to other dh instances we do not wait for execution here
352 //but doing so we can not indicate problems to the caller (who does what with that then?)
353 //by now we just assume straightforward successful execution
354 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
355 // possible problems to the caller later autonomously
356
357 // deadline context to ensure completion of background routines waited for
358 //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 +0530359 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 dctx, cancel := context.WithDeadline(context.Background(), deadline)
361
Girish Gowdra041dcb32020-11-16 16:54:30 -0800362 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000363 pDevEntry.resetKvProcessingErrorIndication()
364
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 var wg sync.WaitGroup
366 wg.Add(2) // for the 2 go routines to finish
367 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
369 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
370 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000371
Girish Gowdra041dcb32020-11-16 16:54:30 -0800372 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 return nil
376}
377
Himani Chawla6d2ae152020-09-02 13:11:20 +0530378func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 msg *ic.InterAdapterMessage) error {
381
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000383
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000387 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
388 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 if dh.pOnuTP == nil {
390 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
395
396 msgBody := msg.GetBody()
397 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
398 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000399 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 "device-id": dh.deviceID, "error": err})
401 return err
402 }
403
404 //compare TECH_PROFILE_DOWNLOAD_REQUEST
405 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406 defer dh.pOnuTP.unlockTpProcMutex()
407 pDevEntry.lockOnuKVStoreMutex()
408 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530409
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410 if delGemPortMsg.UniId > 255 {
411 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
412 delGemPortMsg.UniId, dh.deviceID))
413 }
414 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800415 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
416 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000417 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 -0800418 return err
419 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530420
mpagenkofc4f56e2020-11-04 17:17:49 +0000421 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000422
mpagenkofc4f56e2020-11-04 17:17:49 +0000423 // deadline context to ensure completion of background routines waited for
424 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
425 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426
Girish Gowdra041dcb32020-11-16 16:54:30 -0800427 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000428
mpagenkofc4f56e2020-11-04 17:17:49 +0000429 var wg sync.WaitGroup
430 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000432 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000434
Girish Gowdra041dcb32020-11-16 16:54:30 -0800435 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530436}
437
Himani Chawla6d2ae152020-09-02 13:11:20 +0530438func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000439 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441
dbainbri4d3a0dc2020-12-02 00:33:42 +0000442 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000443
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000446 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
448 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 if dh.pOnuTP == nil {
450 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530454 }
455
456 msgBody := msg.GetBody()
457 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
458 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530460 "device-id": dh.deviceID, "error": err})
461 return err
462 }
463
464 //compare TECH_PROFILE_DOWNLOAD_REQUEST
465 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466 defer dh.pOnuTP.unlockTpProcMutex()
467 pDevEntry.lockOnuKVStoreMutex()
468 defer pDevEntry.unlockOnuKVStoreMutex()
469
470 if delTcontMsg.UniId > 255 {
471 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
472 delTcontMsg.UniId, dh.deviceID))
473 }
474 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800475 tpPath := delTcontMsg.TpPath
476 tpID, err := GetTpIDFromTpPath(tpPath)
477 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800479 return err
480 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530484 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 dctx, cancel := context.WithDeadline(context.Background(), deadline)
486
Girish Gowdra041dcb32020-11-16 16:54:30 -0800487 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000488 pDevEntry.resetKvProcessingErrorIndication()
489
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 var wg sync.WaitGroup
491 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 cResourceTcont, delTcontMsg.AllocId, &wg)
494 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
496 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497
Girish Gowdra041dcb32020-11-16 16:54:30 -0800498 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530499 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 return nil
501}
502
Himani Chawla6d2ae152020-09-02 13:11:20 +0530503//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000504// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
505// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000507 msgID := msg.Header.Id
508 msgType := msg.Header.Type
509 fromTopic := msg.Header.FromTopic
510 toTopic := msg.Header.ToTopic
511 toDeviceID := msg.Header.ToDeviceId
512 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000514 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
515
516 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000517 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000518 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
519 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000520 {
mpagenko057889c2021-01-21 16:51:58 +0000521 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000522 }
mpagenkoaf801632020-07-03 10:00:42 +0000523 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
524 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000526 }
527 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
528 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000529 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000530
mpagenkoaf801632020-07-03 10:00:42 +0000531 }
532 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
533 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000535 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000536 default:
537 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 "msgType": msg.Header.Type, "device-id": dh.deviceID})
540 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000541 }
542 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000543}
544
mpagenkodff5dda2020-08-28 11:52:01 +0000545//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000546func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
547 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000548 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000550
mpagenko01e726e2020-10-23 09:45:29 +0000551 var retError error = nil
552 //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 +0000553 if apOfFlowChanges.ToRemove != nil {
554 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000555 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000556 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000557 "device-id": dh.deviceID})
558 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000559 continue
560 }
561 flowInPort := flow.GetInPort(flowItem)
562 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 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 +0000564 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
565 continue
566 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000567 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000568 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000570 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000571 continue
572 } else {
573 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530574 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000575 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
576 loUniPort = uniPort
577 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000578 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000579 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
580 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
581 flowInPort, dh.deviceID)
582 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000583 }
584 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000585 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000586 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000587 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000589 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000590 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000591 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000592 log.Fields{"device-id": dh.deviceID, "error": err})
593 retError = err
594 continue
595 //return err
596 } else { // if last setting succeeds, overwrite possibly previously set error
597 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000598 }
599 }
600 }
601 }
mpagenko01e726e2020-10-23 09:45:29 +0000602 if apOfFlowChanges.ToAdd != nil {
603 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
604 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000606 "device-id": dh.deviceID})
607 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
608 continue
609 }
610 flowInPort := flow.GetInPort(flowItem)
611 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612 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 +0000613 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
614 continue
615 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
616 } else if flowInPort == dh.ponPortNumber {
617 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000619 "device-id": dh.deviceID, "inPort": flowInPort})
620 continue
621 } else {
622 // this is the relevant upstream flow
623 var loUniPort *onuUniPort
624 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
625 loUniPort = uniPort
626 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000627 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000628 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
629 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
630 flowInPort, dh.deviceID)
631 continue
632 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
633 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000634 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
635 // if not, we just throw some error here to have an indication about that, if we really need to support that
636 // then we would need to create some means to activate the internal stored flows
637 // after the device gets active automatically (and still with its dependency to the TechProfile)
638 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
639 // also abort for the other still possible flows here
640 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000642 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000643 return fmt.Errorf("improper device state on device %s", dh.deviceID)
644 }
645
mpagenko01e726e2020-10-23 09:45:29 +0000646 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000648 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
649 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000651 //try next flow after processing error
652 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000654 log.Fields{"device-id": dh.deviceID, "error": err})
655 retError = err
656 continue
657 //return err
658 } else { // if last setting succeeds, overwrite possibly previously set error
659 retError = nil
660 }
661 }
662 }
663 }
664 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000665}
666
Himani Chawla6d2ae152020-09-02 13:11:20 +0530667//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000668//following are the expected device states after this activity:
669//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
670// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
672 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000673
mpagenko900ee4b2020-10-12 11:56:34 +0000674 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 //note that disableDevice sequences in some 'ONU active' state may yield also
676 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000677 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000678 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000679 //disable-device shall be just a UNi/ONU-G related admin state setting
680 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000681
mpagenkofc4f56e2020-11-04 17:17:49 +0000682 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000683 // disable UNI ports/ONU
684 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
685 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000687 } else { //LockStateFSM already init
688 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000690 }
691 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000693 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000695 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
696 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000698 }
mpagenko01e726e2020-10-23 09:45:29 +0000699 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000700
701 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000703 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300704 }
705}
706
Himani Chawla6d2ae152020-09-02 13:11:20 +0530707//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
709 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000710
mpagenkofc4f56e2020-11-04 17:17:49 +0000711 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
712 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
713 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
714 // for real ONU's that should have nearly no influence
715 // Note that for real ONU's there is anyway a problematic situation with following sequence:
716 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
717 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
718 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
719 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
720
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000721 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000722 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000723 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000725 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000726 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000728 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300729}
730
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
732 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000733
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000735 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000737 return
738 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000739 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000740 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000742 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000744 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000745 dh.reconciling = false
746 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000747 }
Himani Chawla4d908332020-08-31 12:30:20 +0530748 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000749 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
750 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
751 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
752 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000754}
755
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
757 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000758
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000760 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000762 return
763 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000764 dh.pOnuTP.lockTpProcMutex()
765 defer dh.pOnuTP.unlockTpProcMutex()
766
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000767 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000769 log.Fields{"device-id": dh.deviceID})
770 dh.reconciling = false
771 return
772 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000773 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000774 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
775 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000777 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
778 dh.reconciling = false
779 return
780 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800781 for tpID := range uniData.PersTpPathMap {
782 // deadline context to ensure completion of background routines waited for
783 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
784 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000786
Girish Gowdra041dcb32020-11-16 16:54:30 -0800787 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
788 var wg sync.WaitGroup
789 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
791 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800792 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800794 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000795 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000796 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000798 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
799 dh.reconciling = false
800 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000801 }
802}
803
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
805 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000806
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000810 return
811 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000812 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000814 log.Fields{"device-id": dh.deviceID})
815 dh.reconciling = false
816 return
817 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000818 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000819 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
820 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000822 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
823 dh.reconciling = false
824 return
825 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 var uniPort *onuUniPort
827 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000828 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000829 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 return
832 }
833 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000835 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000838 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
839 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000841 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000842 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000844 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000845 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000847 }
848 }
849 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000850 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000852 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
853 dh.reconciling = false
854 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 }
856}
857
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
859 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 +0000860
861 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000862 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000863}
864
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
866 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000867
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000869 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000870 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000872 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000873 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 pDevEntry.lockOnuKVStoreMutex()
875 defer pDevEntry.unlockOnuKVStoreMutex()
876
877 // deadline context to ensure completion of background routines waited for
878 //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 +0530879 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000881
882 pDevEntry.resetKvProcessingErrorIndication()
883
884 var wg sync.WaitGroup
885 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
887 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000888
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000889 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000891}
892
dbainbri4d3a0dc2020-12-02 00:33:42 +0000893func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
894 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300895 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000897 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300898 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530900 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530902 return err
903 }
mpagenko01e726e2020-10-23 09:45:29 +0000904
905 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000906 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000907
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000909 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300911 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000912 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000913 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300914 return err
915 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300917 return err
918 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000919 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000920 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
921 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
922 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
923 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300924 return nil
925}
926
mpagenkoc8bba412021-01-15 15:38:44 +0000927//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
928func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
929 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
930 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000931 //return success to comfort the core processing during integration
932 return nil
933 // TODO!!: also verify error response behavior
934 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000935}
936
Himani Chawla6d2ae152020-09-02 13:11:20 +0530937// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000938// #####################################################################################
939
940// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530941// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000942
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
944 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 +0000945}
946
947// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000949
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000951 var err error
952
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000953 // populate what we know. rest comes later after mib sync
954 dh.device.Root = false
955 dh.device.Vendor = "OpenONU"
956 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000957 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000958 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000959
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000960 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000961
962 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
964 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530965 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000966 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000967 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000968 log.Fields{"device-id": dh.deviceID})
969 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000970
Himani Chawla4d908332020-08-31 12:30:20 +0530971 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000972 dh.ponPortNumber = dh.device.ParentPortNo
973
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000974 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
975 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
976 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000978 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530979 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000980
981 /*
982 self._pon = PonPort.create(self, self._pon_port_number)
983 self._pon.add_peer(self.parent_id, self._pon_port_number)
984 self.logger.debug('adding-pon-port-to-agent',
985 type=self._pon.get_port().type,
986 admin_state=self._pon.get_port().admin_state,
987 oper_status=self._pon.get_port().oper_status,
988 )
989 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000990 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000991 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000992 var ponPortNo uint32 = 1
993 if dh.ponPortNumber != 0 {
994 ponPortNo = dh.ponPortNumber
995 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000996
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000997 pPonPort := &voltha.Port{
998 PortNo: ponPortNo,
999 Label: fmt.Sprintf("pon-%d", ponPortNo),
1000 Type: voltha.Port_PON_ONU,
1001 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301002 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001003 PortNo: ponPortNo}}, // Peer port is parent's port number
1004 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1006 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001007 e.Cancel(err)
1008 return
1009 }
1010 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001012 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001014}
1015
1016// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001018
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001020 var err error
1021 /*
1022 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1023 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1024 return nil
1025 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001026 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1027 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001028 e.Cancel(err)
1029 return
1030 }
1031
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001032 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001034 // reconcilement will be continued after mib download is done
1035 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001036
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001037 /*
1038 ############################################################################
1039 # Setup Alarm handler
1040 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1041 device.serial_number)
1042 ############################################################################
1043 # Setup PM configuration for this device
1044 # Pass in ONU specific options
1045 kwargs = {
1046 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1047 'heartbeat': self.heartbeat,
1048 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1049 }
1050 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1051 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1052 self.logical_device_id, device.serial_number,
1053 grouped=True, freq_override=False, **kwargs)
1054 pm_config = self._pm_metrics.make_proto()
1055 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1056 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1057 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1058
1059 # Note, ONU ID and UNI intf set in add_uni_port method
1060 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1061 ani_ports=[self._pon])
1062
1063 # Code to Run OMCI Test Action
1064 kwargs_omci_test_action = {
1065 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1066 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1067 }
1068 serial_number = device.serial_number
1069 self._test_request = OmciTestRequest(self.core_proxy,
1070 self.omci_agent, self.device_id,
1071 AniG, serial_number,
1072 self.logical_device_id,
1073 exclusive=False,
1074 **kwargs_omci_test_action)
1075
1076 self.enabled = True
1077 else:
1078 self.logger.info('onu-already-activated')
1079 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001080
dbainbri4d3a0dc2020-12-02 00:33:42 +00001081 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001082}
1083
1084// doStateConnected get the device info and update to voltha core
1085// for comparison of the original method (not that easy to uncomment): compare here:
1086// voltha-openolt-adapter/adaptercore/device_handler.go
1087// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001088func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001089
dbainbri4d3a0dc2020-12-02 00:33:42 +00001090 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301091 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001092 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001093 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001094}
1095
1096// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001097func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001098
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301100 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001101 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001103
1104 /*
1105 // Synchronous call to update device state - this method is run in its own go routine
1106 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1107 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001108 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 +00001109 return err
1110 }
1111 return nil
1112 */
1113}
1114
1115// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001117
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119 var err error
1120
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001121 device := dh.device
1122 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001123 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125 e.Cancel(err)
1126 return
1127 }
1128
1129 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001131 /*
1132 // Update the all ports state on that device to disable
1133 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001134 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135 return er
1136 }
1137
1138 //Update the device oper state and connection status
1139 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1140 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1141 dh.device = cloned
1142
1143 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001144 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001145 return er
1146 }
1147
1148 //get the child device for the parent device
1149 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1150 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001151 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001152 return err
1153 }
1154 for _, onuDevice := range onuDevices.Items {
1155
1156 // Update onu state as down in onu adapter
1157 onuInd := oop.OnuIndication{}
1158 onuInd.OperState = "down"
1159 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1160 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1161 if er != nil {
1162 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001163 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001164 //Do not return here and continue to process other ONUs
1165 }
1166 }
1167 // * Discovered ONUs entries need to be cleared , since after OLT
1168 // is up, it starts sending discovery indications again* /
1169 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001170 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001171 return nil
1172 */
Himani Chawla4d908332020-08-31 12:30:20 +05301173 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001174 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176}
1177
Himani Chawla6d2ae152020-09-02 13:11:20 +05301178// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001179// #################################################################################
1180
1181// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301182// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001184//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001185func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001186 dh.lockDevice.RLock()
1187 pOnuDeviceEntry := dh.pOnuOmciDevice
1188 if aWait && pOnuDeviceEntry == nil {
1189 //keep the read sema short to allow for subsequent write
1190 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001191 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001192 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1193 // so it might be needed to wait here for that event with some timeout
1194 select {
1195 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001196 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001197 return nil
1198 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001199 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001200 // if written now, we can return the written value without sema
1201 return dh.pOnuOmciDevice
1202 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203 }
mpagenko3af1f032020-06-10 08:53:41 +00001204 dh.lockDevice.RUnlock()
1205 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206}
1207
Himani Chawla6d2ae152020-09-02 13:11:20 +05301208//setOnuDeviceEntry sets the ONU device entry within the handler
1209func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001210 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001211 dh.lockDevice.Lock()
1212 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001213 dh.pOnuOmciDevice = apDeviceEntry
1214 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001215 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001216}
1217
Himani Chawla6d2ae152020-09-02 13:11:20 +05301218//addOnuDeviceEntry creates a new ONU device or returns the existing
1219func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001221
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001223 if deviceEntry == nil {
1224 /* costum_me_map in python code seems always to be None,
1225 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1226 /* also no 'clock' argument - usage open ...*/
1227 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001228 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001229 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001230 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001231 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001232 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001233 // fire deviceEntry ready event to spread to possibly waiting processing
1234 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001236 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001238 }
1239 // might be updated with some error handling !!!
1240 return nil
1241}
1242
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1244 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001245 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1246
1247 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001248
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001250 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001252 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1253 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001254 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 if err := dh.storePersistentData(ctx); err != nil {
1256 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001257 log.Fields{"device-id": dh.deviceID, "err": err})
1258 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001260 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001261 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001262 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1263 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001265 }
1266 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001268 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001269
1270 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 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 +00001272 log.Fields{"device-id": dh.deviceID})
1273 dh.reconciling = false
1274 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001275 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001276 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1277 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1278 // 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 +00001279 // 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 +00001280 // so let's just try to keep it simple ...
1281 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001283 if err != nil || device == nil {
1284 //TODO: needs to handle error scenarios
1285 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1286 return errors.New("Voltha Device not found")
1287 }
1288 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001289
dbainbri4d3a0dc2020-12-02 00:33:42 +00001290 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001291 return err
mpagenko3af1f032020-06-10 08:53:41 +00001292 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001293
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001295
1296 /* this might be a good time for Omci Verify message? */
1297 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001299 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001300 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001302
1303 /* give the handler some time here to wait for the OMCi verification result
1304 after Timeout start and try MibUpload FSM anyway
1305 (to prevent stopping on just not supported OMCI verification from ONU) */
1306 select {
1307 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001308 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001309 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001310 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001311 }
1312
1313 /* In py code it looks earlier (on activate ..)
1314 # Code to Run OMCI Test Action
1315 kwargs_omci_test_action = {
1316 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1317 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1318 }
1319 serial_number = device.serial_number
1320 self._test_request = OmciTestRequest(self.core_proxy,
1321 self.omci_agent, self.device_id,
1322 AniG, serial_number,
1323 self.logical_device_id,
1324 exclusive=False,
1325 **kwargs_omci_test_action)
1326 ...
1327 # Start test requests after a brief pause
1328 if not self._test_request_started:
1329 self._test_request_started = True
1330 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1331 reactor.callLater(tststart, self._test_request.start_collector)
1332
1333 */
1334 /* which is then: in omci_test_request.py : */
1335 /*
1336 def start_collector(self, callback=None):
1337 """
1338 Start the collection loop for an adapter if the frequency > 0
1339
1340 :param callback: (callable) Function to call to collect PM data
1341 """
1342 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1343 if callback is None:
1344 callback = self.perform_test_omci
1345
1346 if self.lc is None:
1347 self.lc = LoopingCall(callback)
1348
1349 if self.default_freq > 0:
1350 self.lc.start(interval=self.default_freq / 10)
1351
1352 def perform_test_omci(self):
1353 """
1354 Perform the initial test request
1355 """
1356 ani_g_entities = self._device.configuration.ani_g_entities
1357 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1358 is not None else None
1359 self._entity_id = ani_g_entities_ids[0]
1360 self.logger.info('perform-test', entity_class=self._entity_class,
1361 entity_id=self._entity_id)
1362 try:
1363 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1364 result = yield self._device.omci_cc.send(frame)
1365 if not result.fields['omci_message'].fields['success_code']:
1366 self.logger.info('Self-Test Submitted Successfully',
1367 code=result.fields[
1368 'omci_message'].fields['success_code'])
1369 else:
1370 raise TestFailure('Test Failure: {}'.format(
1371 result.fields['omci_message'].fields['success_code']))
1372 except TimeoutError as e:
1373 self.deferred.errback(failure.Failure(e))
1374
1375 except Exception as e:
1376 self.logger.exception('perform-test-Error', e=e,
1377 class_id=self._entity_class,
1378 entity_id=self._entity_id)
1379 self.deferred.errback(failure.Failure(e))
1380
1381 */
1382
1383 // PM related heartbeat??? !!!TODO....
1384 //self._heartbeat.enabled = True
1385
mpagenko1cc3cb42020-07-27 15:24:38 +00001386 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1387 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1388 * 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 +05301389 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001390 */
1391 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001392 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001393 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001394 if pMibUlFsm.Is(ulStDisabled) {
1395 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001396 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 +00001397 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301398 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301400 //Determine ONU status and start/re-start MIB Synchronization tasks
1401 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001402 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301403 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 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 +00001405 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001406 }
Himani Chawla4d908332020-08-31 12:30:20 +05301407 } else {
1408 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001409 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 +00001410 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301411 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001412 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001413 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001414 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001415 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001416 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001417 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001418 }
1419 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001421 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001422 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001423
1424 // Start PM collector routine
1425 go dh.startCollector(ctx)
1426
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001427 return nil
1428}
1429
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001431 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001432 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001433 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001434 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001435
mpagenko900ee4b2020-10-12 11:56:34 +00001436 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1437 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1438 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 if err := dh.resetFsms(ctx); err != nil {
1440 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001441 log.Fields{"device-id": dh.deviceID, "error": err})
1442 // abort: system behavior is just unstable ...
1443 return err
1444 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001445 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 _ = 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 +00001447
1448 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1449 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1450 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001452 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001453 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001454 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001455 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001457
1458 //TODO!!! remove existing traffic profiles
1459 /* from py code, if TP's exist, remove them - not yet implemented
1460 self._tp = dict()
1461 # Let TP download happen again
1462 for uni_id in self._tp_service_specific_task:
1463 self._tp_service_specific_task[uni_id].clear()
1464 for uni_id in self._tech_profile_download_done:
1465 self._tech_profile_download_done[uni_id].clear()
1466 */
1467
dbainbri4d3a0dc2020-12-02 00:33:42 +00001468 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001469
mpagenkofc4f56e2020-11-04 17:17:49 +00001470 dh.ReadyForSpecificOmciConfig = false
1471
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001473 // abort: system behavior is just unstable ...
1474 return err
1475 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001476 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001477 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001478 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001479 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001480 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001482 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001483 // abort: system behavior is just unstable ...
1484 return err
1485 }
1486 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001488 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001489 return nil
1490}
1491
dbainbri4d3a0dc2020-12-02 00:33:42 +00001492func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001493 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1494 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1495 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1496 // and using the stop/reset event should never harm
1497
dbainbri4d3a0dc2020-12-02 00:33:42 +00001498 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001499 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001501 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1502 }
mpagenko900ee4b2020-10-12 11:56:34 +00001503 //the MibSync FSM might be active all the ONU-active time,
1504 // hence it must be stopped unconditionally
1505 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1506 if pMibUlFsm != nil {
1507 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1508 }
1509 //MibDownload may run
1510 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1511 if pMibDlFsm != nil {
1512 _ = pMibDlFsm.Event(dlEvReset)
1513 }
1514 //port lock/unlock FSM's may be active
1515 if dh.pUnlockStateFsm != nil {
1516 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1517 }
1518 if dh.pLockStateFsm != nil {
1519 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1520 }
1521 //techProfile related PonAniConfigFsm FSM may be active
1522 if dh.pOnuTP != nil {
1523 // should always be the case here
1524 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1525 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001526 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1527 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1528 }
mpagenko900ee4b2020-10-12 11:56:34 +00001529 }
1530 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001531 // reset the possibly existing VlanConfigFsm
1532 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1533 //VlanFilterFsm exists and was already started
1534 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1535 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001536 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001537 // no need to remove specific data
1538 pVlanFilterFsm.RequestClearPersistency(false)
1539 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001540 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1541 }
1542 }
1543 }
1544 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001545 // Stop collector routine for PM Counters
1546 dh.stopCollector <- true
1547
mpagenko900ee4b2020-10-12 11:56:34 +00001548 return nil
1549}
1550
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1552 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 +05301553
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1555 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001556 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001558 return
1559 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001560 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001561 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1562 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1563 for _, mgmtEntityID := range pptpInstKeys {
1564 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1565 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301567 i++
1568 }
1569 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301571 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001572 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1573 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301574 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001575 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301576 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301578 i++
1579 }
1580 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301582 }
1583 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301585 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001586 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1587 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1588 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1589 * disable/enable toggling here to allow traffic
1590 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1591 * like the py comment says:
1592 * # start by locking all the unis till mib sync and initial mib is downloaded
1593 * # this way we can capture the port down/up events when we are ready
1594 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301595
mpagenkoa40e99a2020-11-17 13:50:39 +00001596 // Init Uni Ports to Admin locked state
1597 // *** should generate UniLockStateDone event *****
1598 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001600 } else { //LockStateFSM already init
1601 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001603 }
1604}
1605
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1607 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301608 /* Mib download procedure -
1609 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1610 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001612 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001614 return
1615 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301616 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1617 if pMibDlFsm != nil {
1618 if pMibDlFsm.Is(dlStDisabled) {
1619 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 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 +05301621 // maybe try a FSM reset and then again ... - TODO!!!
1622 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301624 // maybe use more specific states here for the specific download steps ...
1625 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301627 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301629 //Begin MIB data download (running autonomously)
1630 }
1631 }
1632 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001634 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301635 // maybe try a FSM reset and then again ... - TODO!!!
1636 }
1637 /***** Mib download started */
1638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301640 }
1641}
1642
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1644 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301645 //initiate DevStateUpdate
1646 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001648 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301650 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1651 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301655 }
1656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001658 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001660 return
1661 }
1662 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 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 +00001664 log.Fields{"device-id": dh.deviceID})
1665 dh.reconciling = false
1666 return
1667 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301669 log.Fields{"device-id": dh.deviceID})
1670 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001671 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001672 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301673 // *** should generate UniUnlockStateDone event *****
1674 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301677 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301679 }
1680}
1681
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1683 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301684
1685 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301687 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1689 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001690 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001692 return
1693 }
1694 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 if err := dh.storePersistentData(ctx); err != nil {
1696 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001697 log.Fields{"device-id": dh.deviceID, "err": err})
1698 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301699 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700 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 +05301701 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001703 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301704 }
1705}
1706
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1708 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001709 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001711 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1712 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001714 }
1715
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001717 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001719
1720 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001721 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001722
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 return
1727 }
1728 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 if err := dh.storePersistentData(ctx); err != nil {
1730 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001731 log.Fields{"device-id": dh.deviceID, "err": err})
1732 }
mpagenko900ee4b2020-10-12 11:56:34 +00001733}
1734
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1736 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001737 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001739 voltha.OperStatus_ACTIVE); err != nil {
1740 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001742 }
1743
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001745 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001746 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001748
1749 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001751
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001753 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001755 return
1756 }
1757 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 if err := dh.storePersistentData(ctx); err != nil {
1759 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001760 log.Fields{"device-id": dh.deviceID, "err": err})
1761 }
mpagenko900ee4b2020-10-12 11:56:34 +00001762}
1763
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001765 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001767 // attention: the device reason update is done based on ONU-UNI-Port related activity
1768 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001769 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001770 // 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 +00001771 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301772 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001773 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001775 }
1776 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001778 // attention: the device reason update is done based on ONU-UNI-Port related activity
1779 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001780 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001781 // 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 +00001782 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001783 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001784 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301785}
1786
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1788 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001789 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301790 // attention: the device reason update is done based on ONU-UNI-Port related activity
1791 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301792
mpagenkofc4f56e2020-11-04 17:17:49 +00001793 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001794 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001795 // which may be the case from some previous actvity on another UNI Port of the ONU
1796 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001798 // request MDS-value for test and logging purposes
1799 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001800 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001802 }
1803 }
1804 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001805 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001806 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001808 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301809 }
1810}
1811
Himani Chawla6d2ae152020-09-02 13:11:20 +05301812//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301814 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001815 case MibDatabaseSync:
1816 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001818 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001819 case UniLockStateDone:
1820 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001822 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001823 case MibDownloadDone:
1824 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001826 }
1827 case UniUnlockStateDone:
1828 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001830 }
mpagenko900ee4b2020-10-12 11:56:34 +00001831 case UniEnableStateDone:
1832 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001833 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001834 }
1835 case UniDisableStateDone:
1836 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001837 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001838 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001839 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001840 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001842 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001843 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001844 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001846 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001847 default:
1848 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001850 }
1851 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001852}
1853
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001855 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301857 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001858 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301861 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001863 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001865 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001866 //store UniPort with the System-PortNumber key
1867 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001868 if !dh.reconciling {
1869 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1871 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001872 } //error logging already within UniPort method
1873 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001875 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001876 }
1877 }
1878}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001879
mpagenko3af1f032020-06-10 08:53:41 +00001880// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001882 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301883 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001884 // with following remark:
1885 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1886 // # load on the core
1887
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001888 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001889
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001890 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001891 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301892 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301894 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001895 if !dh.reconciling {
1896 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 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 +00001898 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001899 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001901 }
mpagenko3af1f032020-06-10 08:53:41 +00001902 }
1903 }
1904}
1905
1906// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001908 // compare enableUniPortStateUpdate() above
1909 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1910 for uniNo, uniPort := range dh.uniEntityMap {
1911 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301912 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001913 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301914 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001915 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 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 +00001917 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001918 }
1919}
1920
1921// ONU_Active/Inactive announcement on system KAFKA bus
1922// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001924 var de voltha.DeviceEvent
1925 eventContext := make(map[string]string)
1926 //Populating event context
1927 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001929 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301931 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001932 }
1933 oltSerialNumber := parentDevice.SerialNumber
1934
1935 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1936 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1937 eventContext["serial-number"] = dh.device.SerialNumber
1938 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301939 eventContext["device_id"] = aDeviceID
1940 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001942 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001943
1944 /* Populating device event body */
1945 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301946 de.ResourceId = aDeviceID
1947 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001948 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1949 de.Description = fmt.Sprintf("%s Event - %s - %s",
1950 cEventObjectType, cOnuActivatedEvent, "Raised")
1951 } else {
1952 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1953 de.Description = fmt.Sprintf("%s Event - %s - %s",
1954 cEventObjectType, cOnuActivatedEvent, "Cleared")
1955 }
1956 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1958 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301959 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001960 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301962 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001963}
1964
Himani Chawla4d908332020-08-31 12:30:20 +05301965// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001967 chLSFsm := make(chan Message, 2048)
1968 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301969 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001971 sFsmName = "LockStateFSM"
1972 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001974 sFsmName = "UnLockStateFSM"
1975 }
mpagenko3af1f032020-06-10 08:53:41 +00001976
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001978 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001980 return
1981 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001983 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001984 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301985 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001986 dh.pLockStateFsm = pLSFsm
1987 } else {
1988 dh.pUnlockStateFsm = pLSFsm
1989 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001991 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001993 }
1994}
1995
1996// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001998 /* Uni Port lock/unlock procedure -
1999 ***** should run via 'adminDone' state and generate the argument requested event *****
2000 */
2001 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302002 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002003 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2004 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2005 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002006 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302007 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002008 }
2009 } else {
2010 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2011 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2012 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002013 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302014 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002015 }
2016 }
2017 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002018 if pLSStatemachine.Is(uniStDisabled) {
2019 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002021 // maybe try a FSM reset and then again ... - TODO!!!
2022 } else {
2023 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002025 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002026 }
2027 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002028 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002029 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002030 // maybe try a FSM reset and then again ... - TODO!!!
2031 }
2032 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002034 // maybe try a FSM reset and then again ... - TODO!!!
2035 }
2036}
2037
Himani Chawla6d2ae152020-09-02 13:11:20 +05302038//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002040 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002042 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002043 kvbackend := &db.Backend{
2044 Client: dh.pOpenOnuAc.kvClient,
2045 StoreType: dh.pOpenOnuAc.KVStoreType,
2046 /* address config update acc. to [VOL-2736] */
2047 Address: addr,
2048 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2049 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002050
mpagenkoaf801632020-07-03 10:00:42 +00002051 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002052}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002053func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302054 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002055
mpagenkodff5dda2020-08-28 11:52:01 +00002056 for _, field := range flow.GetOfbFields(apFlowItem) {
2057 switch field.Type {
2058 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2059 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002061 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2062 }
mpagenko01e726e2020-10-23 09:45:29 +00002063 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002064 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2065 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302066 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002067 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302068 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2069 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002070 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2071 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002072 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2073 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302074 return
mpagenkodff5dda2020-08-28 11:52:01 +00002075 }
2076 }
mpagenko01e726e2020-10-23 09:45:29 +00002077 */
mpagenkodff5dda2020-08-28 11:52:01 +00002078 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2079 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302080 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002081 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302082 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002083 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302084 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002085 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002086 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302087 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002088 }
2089 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2090 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302091 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002092 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002093 "PCP": loAddPcp})
2094 }
2095 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2096 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002097 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002098 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2099 }
2100 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2101 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002103 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2104 }
2105 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2106 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002108 "IPv4-DST": field.GetIpv4Dst()})
2109 }
2110 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2111 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002112 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002113 "IPv4-SRC": field.GetIpv4Src()})
2114 }
2115 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2116 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002118 "Metadata": field.GetTableMetadata()})
2119 }
2120 /*
2121 default:
2122 {
2123 //all other entires ignored
2124 }
2125 */
2126 }
2127 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302128}
mpagenkodff5dda2020-08-28 11:52:01 +00002129
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002131 for _, action := range flow.GetActions(apFlowItem) {
2132 switch action.Type {
2133 /* not used:
2134 case of.OfpActionType_OFPAT_OUTPUT:
2135 {
mpagenko01e726e2020-10-23 09:45:29 +00002136 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002137 "Output": action.GetOutput()})
2138 }
2139 */
2140 case of.OfpActionType_OFPAT_PUSH_VLAN:
2141 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002143 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2144 }
2145 case of.OfpActionType_OFPAT_SET_FIELD:
2146 {
2147 pActionSetField := action.GetSetField()
2148 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002149 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002150 "OxcmClass": pActionSetField.Field.OxmClass})
2151 }
2152 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302153 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002154 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302155 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002156 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302159 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002160 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002162 "Type": pActionSetField.Field.GetOfbField().Type})
2163 }
2164 }
2165 /*
2166 default:
2167 {
2168 //all other entires ignored
2169 }
2170 */
2171 }
2172 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302173}
2174
2175//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302177 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2178 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2179 var loAddPcp, loSetPcp uint8
2180 var loIPProto uint32
2181 /* the TechProfileId is part of the flow Metadata - compare also comment within
2182 * OLT-Adapter:openolt_flowmgr.go
2183 * Metadata 8 bytes:
2184 * Most Significant 2 Bytes = Inner VLAN
2185 * Next 2 Bytes = Tech Profile ID(TPID)
2186 * Least Significant 4 Bytes = Port ID
2187 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2188 * subscriber related flows.
2189 */
2190
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302192 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302194 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002195 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302196 }
mpagenko551a4d42020-12-08 18:09:20 +00002197 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002198 loCookie := apFlowItem.GetCookie()
2199 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002201 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302202
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002204 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302205 if loIPProto == 2 {
2206 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2207 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002208 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2209 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302210 return nil
2211 }
mpagenko01e726e2020-10-23 09:45:29 +00002212 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002214
2215 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002217 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2218 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2219 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2220 //TODO!!: Use DeviceId within the error response to rwCore
2221 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002222 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002223 }
2224 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002226 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2227 } else {
2228 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2229 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2230 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302231 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002232 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002233 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002234 }
mpagenko9a304ea2020-12-16 15:54:01 +00002235
2236 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2237 dh.lockVlanConfig.Lock()
2238 defer dh.lockVlanConfig.Unlock()
2239 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302240 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002242 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002243 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002245 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002246}
2247
2248//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002250 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2251 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2252 //no extra check is done on the rule parameters
2253 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2254 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2255 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2256 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002257 // - 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 +00002258 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002260
2261 /* TT related temporary workaround - should not be needed anymore
2262 for _, field := range flow.GetOfbFields(apFlowItem) {
2263 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2264 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002265 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002266 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2267 if loIPProto == 2 {
2268 // 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 +00002269 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002270 log.Fields{"device-id": dh.deviceID})
2271 return nil
2272 }
2273 }
2274 } //for all OfbFields
2275 */
2276
mpagenko9a304ea2020-12-16 15:54:01 +00002277 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2278 dh.lockVlanConfig.Lock()
2279 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002280 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002281 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002282 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002283 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002284 log.Fields{"device-id": dh.deviceID})
2285 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002286 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002288
mpagenko01e726e2020-10-23 09:45:29 +00002289 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002290}
2291
Himani Chawla26e555c2020-08-31 12:30:20 +05302292// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002293// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002294func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002295 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002296 chVlanFilterFsm := make(chan Message, 2048)
2297
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002299 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002300 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302301 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002302 }
2303
dbainbri4d3a0dc2020-12-02 00:33:42 +00002304 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002305 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2306 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002307 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302308 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002309 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2310 if pVlanFilterStatemachine != nil {
2311 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2312 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302314 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002315 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302316 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302318 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2319 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002320 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002321 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002322 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302323 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002324 }
2325 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002327 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302328 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002329 }
2330 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002332 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302333 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002334 }
2335 return nil
2336}
2337
mpagenkofc4f56e2020-11-04 17:17:49 +00002338//VerifyVlanConfigRequest checks on existence of a given uniPort
2339// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002340func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002341 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2342 var pCurrentUniPort *onuUniPort
2343 for _, uniPort := range dh.uniEntityMap {
2344 // only if this port is validated for operState transfer
2345 if uniPort.uniID == uint8(aUniID) {
2346 pCurrentUniPort = uniPort
2347 break //found - end search loop
2348 }
2349 }
2350 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002351 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002352 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2353 return
2354 }
mpagenko551a4d42020-12-08 18:09:20 +00002355 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002356}
2357
mpagenkodff5dda2020-08-28 11:52:01 +00002358//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002359func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002360 //TODO!! verify and start pending flow configuration
2361 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2362 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302363 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002364 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2365 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2366 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002367 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2368 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2369 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2370 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2371 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2372 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2373 } else {
2374 /***** UniVlanConfigFsm continued */
2375 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2376 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2377 "UniPort": apUniPort.portNo})
2378 }
2379 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2380 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2381 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2382 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2383 } else {
2384 /***** UniVlanConfigFsm continued */
2385 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2386 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2387 "UniPort": apUniPort.portNo})
2388 }
mpagenkodff5dda2020-08-28 11:52:01 +00002389 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002390 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2391 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002392 "UniPort": apUniPort.portNo})
2393 }
2394 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002395 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2396 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2397 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002398 }
2399 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002401 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002402 }
mpagenkodff5dda2020-08-28 11:52:01 +00002403 } // else: nothing to do
2404}
2405
2406//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2407// 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 +00002408func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2409 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002410 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2411 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302412 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002413}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002414
2415//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2416//available for potential reconcilement
2417
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002419
2420 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002421 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002422 return nil
2423 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002425
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002427 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002429 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2430 }
2431 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2432
2433 pDevEntry.lockOnuKVStoreMutex()
2434 defer pDevEntry.unlockOnuKVStoreMutex()
2435
2436 // deadline context to ensure completion of background routines waited for
2437 //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 +05302438 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002439 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2440
2441 pDevEntry.resetKvProcessingErrorIndication()
2442 var wg sync.WaitGroup
2443 wg.Add(1) // for the 1 go routine to finish
2444
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2446 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002447
2448 return pDevEntry.getKvProcessingErrorIndication()
2449}
2450
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002452 defer cancel() //ensure termination of context (may be pro forma)
2453 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002455 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002456}
2457
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002459
2460 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002461 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002462 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2464 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002465 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002466 return err
2467 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002468 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002469 return nil
2470 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002472 return nil
2473}
2474
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2476 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002477 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002478 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002479 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2480 }
2481 pDevEntry.lockOnuKVStoreMutex()
2482 defer pDevEntry.unlockOnuKVStoreMutex()
2483
2484 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2485 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2486
2487 pDevEntry.resetKvProcessingErrorIndication()
2488 var wg sync.WaitGroup
2489 wg.Add(1) // for the 1 go routine to finish
2490
2491 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002493
2494 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002496 return err
2497 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002498 return nil
2499}
2500
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002501func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2502 var errStr string = ""
2503 for _, err := range errS {
2504 if err != nil {
2505 errStr = errStr + err.Error() + " "
2506 }
2507 }
2508 if errStr != "" {
2509 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2510 }
2511 return nil
2512}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002513
2514// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2515func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2516 dh.lockDevice.RLock()
2517 defer dh.lockDevice.RUnlock()
2518 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2519 return uniPort.entityID, nil
2520 }
2521 return 0, errors.New("error-fetching-uni-port")
2522}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002523
2524// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002525func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2526 var errorsList []error
2527 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 -08002528
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002529 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2530 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2531 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2532
2533 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2534 // successfully.
2535 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2536 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2537 if len(errorsList) > 0 {
2538 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2539 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002540 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002541 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2542 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002543}
2544
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002545func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2546 var err error
2547 var errorsList []error
2548 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2549
2550 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2551 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2552 errorsList = append(errorsList, err)
2553 }
2554 }
2555
2556 return errorsList
2557}
2558
2559func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2560 var err error
2561 var errorsList []error
2562 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2563 // Check if group metric related config is updated
2564 for _, v := range pmConfigs.Groups {
2565 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2566 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2567 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2568
2569 if ok && m.frequency != v.GroupFreq {
2570 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2571 errorsList = append(errorsList, err)
2572 }
2573 }
2574 if ok && m.enabled != v.Enabled {
2575 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2576 errorsList = append(errorsList, err)
2577 }
2578 }
2579 }
2580 return errorsList
2581}
2582
2583func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2584 var err error
2585 var errorsList []error
2586 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2587 // Check if standalone metric related config is updated
2588 for _, v := range pmConfigs.Metrics {
2589 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2590 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.Name]
2591 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2592
2593 if ok && m.frequency != v.SampleFreq {
2594 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2595 errorsList = append(errorsList, err)
2596 }
2597 }
2598 if ok && m.enabled != v.Enabled {
2599 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2600 errorsList = append(errorsList, err)
2601 }
2602 }
2603 }
2604 return errorsList
2605}
2606
2607// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002608func (dh *deviceHandler) startCollector(ctx context.Context) {
2609 logger.Debugf(ctx, "startingCollector")
2610
2611 // Start routine to process OMCI GET Responses
2612 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002613 // Initialize the next metric collection time.
2614 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2615 // reset like onu rebooted.
2616 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002617 for {
2618 select {
2619 case <-dh.stopCollector:
2620 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2621 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2622 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002623 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2624 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2625 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2626 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2627 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
2628 }
2629 // Update the next metric collection time.
2630 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
2631 } else {
2632 if dh.pmConfigs.Grouped { // metrics are managed as a group
2633 // parse through the group and standalone metrics to see it is time to collect their metrics
2634 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002635
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002636 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2637 // If the group is enabled AND (current time is equal to OR after nextCollectionInterval, collect the group metric)
2638 if g.enabled && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
2639 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2640 }
2641 }
2642 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2643 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2644 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2645 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2646 }
2647 }
2648 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2649
2650 // parse through the group and update the next metric collection time
2651 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2652 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2653 // If group enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2654 if g.enabled && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
2655 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2656 }
2657 }
2658 // parse through the standalone metrics and update the next metric collection time
2659 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2660 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2661 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2662 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2663 }
2664 }
2665 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2666 } /* else { // metrics are not managed as a group
2667 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2668 } */
2669 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002670 }
2671 }
2672}