blob: bc8a185b8beb88f1134ab8a9fa2829e3a7270ed5 [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 Gowdraaf0ad632021-01-27 13:00:01 -0800259 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
260 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800261 // Now, set the initial PM configuration for that device
262 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
263 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
264 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800265 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000266 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000267 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 }
269
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270}
271
mpagenko057889c2021-01-21 16:51:58 +0000272func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530273 msgBody := msg.GetBody()
274 omciMsg := &ic.InterAdapterOmciMessage{}
275 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000276 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530277 "device-id": dh.deviceID, "error": err})
278 return err
279 }
280
281 //assuming omci message content is hex coded!
282 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000283 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530284 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
285 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000286 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530287 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000288 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000290 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000291 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 +0530292 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000293 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000294 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530295}
296
Himani Chawla6d2ae152020-09-02 13:11:20 +0530297func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530299 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000300
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000302
dbainbri4d3a0dc2020-12-02 00:33:42 +0000303 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000304 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000306 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
307 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530308 if dh.pOnuTP == nil {
309 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530311 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000312 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530313 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000314 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000315 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000316 "device-state": deviceReasonMap[dh.deviceReason]})
317 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530318 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000319 //previous state test here was just this one, now extended for more states to reject the SetRequest:
320 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
321 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530322
323 msgBody := msg.GetBody()
324 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
325 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 "device-id": dh.deviceID, "error": err})
328 return err
329 }
330
331 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000332 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
333 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530334 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000335 defer dh.pOnuTP.unlockTpProcMutex()
336 pDevEntry.lockOnuKVStoreMutex()
337 defer pDevEntry.unlockOnuKVStoreMutex()
338
339 if techProfMsg.UniId > 255 {
340 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
341 techProfMsg.UniId, dh.deviceID))
342 }
343 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800344 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
345 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800347 return err
348 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000349
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 // if there has been some change for some uni TechProfilePath
352 //in order to allow concurrent calls to other dh instances we do not wait for execution here
353 //but doing so we can not indicate problems to the caller (who does what with that then?)
354 //by now we just assume straightforward successful execution
355 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
356 // possible problems to the caller later autonomously
357
358 // deadline context to ensure completion of background routines waited for
359 //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 +0530360 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 dctx, cancel := context.WithDeadline(context.Background(), deadline)
362
Girish Gowdra041dcb32020-11-16 16:54:30 -0800363 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364 pDevEntry.resetKvProcessingErrorIndication()
365
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 var wg sync.WaitGroup
367 wg.Add(2) // for the 2 go routines to finish
368 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
370 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
371 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 return nil
377}
378
Himani Chawla6d2ae152020-09-02 13:11:20 +0530379func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000380 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 msg *ic.InterAdapterMessage) error {
382
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000384
dbainbri4d3a0dc2020-12-02 00:33:42 +0000385 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000387 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
389 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 if dh.pOnuTP == nil {
391 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000392 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 }
396
397 msgBody := msg.GetBody()
398 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
399 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000400 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 "device-id": dh.deviceID, "error": err})
402 return err
403 }
404
405 //compare TECH_PROFILE_DOWNLOAD_REQUEST
406 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000407 defer dh.pOnuTP.unlockTpProcMutex()
408 pDevEntry.lockOnuKVStoreMutex()
409 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530410
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411 if delGemPortMsg.UniId > 255 {
412 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
413 delGemPortMsg.UniId, dh.deviceID))
414 }
415 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800416 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
417 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 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 -0800419 return err
420 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530421
mpagenkofc4f56e2020-11-04 17:17:49 +0000422 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423
mpagenkofc4f56e2020-11-04 17:17:49 +0000424 // deadline context to ensure completion of background routines waited for
425 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
426 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000427
Girish Gowdra041dcb32020-11-16 16:54:30 -0800428 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000429
mpagenkofc4f56e2020-11-04 17:17:49 +0000430 var wg sync.WaitGroup
431 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000433 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000434 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000435
Girish Gowdra041dcb32020-11-16 16:54:30 -0800436 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530437}
438
Himani Chawla6d2ae152020-09-02 13:11:20 +0530439func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000440 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530441 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000444
dbainbri4d3a0dc2020-12-02 00:33:42 +0000445 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000446 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000447 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
449 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530450 if dh.pOnuTP == nil {
451 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000452 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000454 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 }
456
457 msgBody := msg.GetBody()
458 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
459 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000460 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530461 "device-id": dh.deviceID, "error": err})
462 return err
463 }
464
465 //compare TECH_PROFILE_DOWNLOAD_REQUEST
466 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467 defer dh.pOnuTP.unlockTpProcMutex()
468 pDevEntry.lockOnuKVStoreMutex()
469 defer pDevEntry.unlockOnuKVStoreMutex()
470
471 if delTcontMsg.UniId > 255 {
472 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
473 delTcontMsg.UniId, dh.deviceID))
474 }
475 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800476 tpPath := delTcontMsg.TpPath
477 tpID, err := GetTpIDFromTpPath(tpPath)
478 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800480 return err
481 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530485 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 dctx, cancel := context.WithDeadline(context.Background(), deadline)
487
Girish Gowdra041dcb32020-11-16 16:54:30 -0800488 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000489 pDevEntry.resetKvProcessingErrorIndication()
490
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 var wg sync.WaitGroup
492 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 cResourceTcont, delTcontMsg.AllocId, &wg)
495 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
497 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498
Girish Gowdra041dcb32020-11-16 16:54:30 -0800499 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 return nil
502}
503
Himani Chawla6d2ae152020-09-02 13:11:20 +0530504//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000505// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
506// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000508 msgID := msg.Header.Id
509 msgType := msg.Header.Type
510 fromTopic := msg.Header.FromTopic
511 toTopic := msg.Header.ToTopic
512 toDeviceID := msg.Header.ToDeviceId
513 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000515 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
516
517 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000518 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000519 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
520 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000521 {
mpagenko057889c2021-01-21 16:51:58 +0000522 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000523 }
mpagenkoaf801632020-07-03 10:00:42 +0000524 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
525 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000527 }
528 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
529 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000531
mpagenkoaf801632020-07-03 10:00:42 +0000532 }
533 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
534 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000535 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000536 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000537 default:
538 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540 "msgType": msg.Header.Type, "device-id": dh.deviceID})
541 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000542 }
543 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000544}
545
mpagenkodff5dda2020-08-28 11:52:01 +0000546//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
548 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000549 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000550 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000551
mpagenko01e726e2020-10-23 09:45:29 +0000552 var retError error = nil
553 //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 +0000554 if apOfFlowChanges.ToRemove != nil {
555 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000556 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000557 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000558 "device-id": dh.deviceID})
559 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000560 continue
561 }
562 flowInPort := flow.GetInPort(flowItem)
563 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 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 +0000565 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
566 continue
567 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000568 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000569 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000571 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000572 continue
573 } else {
574 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530575 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000576 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
577 loUniPort = uniPort
578 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000580 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
581 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
582 flowInPort, dh.deviceID)
583 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000584 }
585 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000587 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000588 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000590 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000591 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000592 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000593 log.Fields{"device-id": dh.deviceID, "error": err})
594 retError = err
595 continue
596 //return err
597 } else { // if last setting succeeds, overwrite possibly previously set error
598 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000599 }
600 }
601 }
602 }
mpagenko01e726e2020-10-23 09:45:29 +0000603 if apOfFlowChanges.ToAdd != nil {
604 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
605 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000606 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000607 "device-id": dh.deviceID})
608 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
609 continue
610 }
611 flowInPort := flow.GetInPort(flowItem)
612 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 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 +0000614 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
615 continue
616 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
617 } else if flowInPort == dh.ponPortNumber {
618 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000620 "device-id": dh.deviceID, "inPort": flowInPort})
621 continue
622 } else {
623 // this is the relevant upstream flow
624 var loUniPort *onuUniPort
625 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
626 loUniPort = uniPort
627 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000628 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000629 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
630 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
631 flowInPort, dh.deviceID)
632 continue
633 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
634 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000635 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
636 // if not, we just throw some error here to have an indication about that, if we really need to support that
637 // then we would need to create some means to activate the internal stored flows
638 // after the device gets active automatically (and still with its dependency to the TechProfile)
639 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
640 // also abort for the other still possible flows here
641 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000643 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000644 return fmt.Errorf("improper device state on device %s", dh.deviceID)
645 }
646
mpagenko01e726e2020-10-23 09:45:29 +0000647 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000649 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
650 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000651 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000652 //try next flow after processing error
653 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000655 log.Fields{"device-id": dh.deviceID, "error": err})
656 retError = err
657 continue
658 //return err
659 } else { // if last setting succeeds, overwrite possibly previously set error
660 retError = nil
661 }
662 }
663 }
664 }
665 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000666}
667
Himani Chawla6d2ae152020-09-02 13:11:20 +0530668//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000669//following are the expected device states after this activity:
670//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
671// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
673 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000674
mpagenko900ee4b2020-10-12 11:56:34 +0000675 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000676 //note that disableDevice sequences in some 'ONU active' state may yield also
677 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000678 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000679 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000680 //disable-device shall be just a UNi/ONU-G related admin state setting
681 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000682
mpagenkofc4f56e2020-11-04 17:17:49 +0000683 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000684 // disable UNI ports/ONU
685 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
686 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000688 } else { //LockStateFSM already init
689 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000690 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000691 }
692 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000694 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000696 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
697 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000699 }
mpagenko01e726e2020-10-23 09:45:29 +0000700 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000701
702 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000704 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300705 }
706}
707
Himani Chawla6d2ae152020-09-02 13:11:20 +0530708//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
710 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000711
mpagenkofc4f56e2020-11-04 17:17:49 +0000712 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
713 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
714 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
715 // for real ONU's that should have nearly no influence
716 // Note that for real ONU's there is anyway a problematic situation with following sequence:
717 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
718 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
719 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
720 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
721
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000722 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000723 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000724 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000725 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000726 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000727 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000729 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300730}
731
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
733 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000734
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000736 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000738 return
739 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000741 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000742 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000743 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000744 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000745 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000746 dh.reconciling = false
747 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000748 }
Himani Chawla4d908332020-08-31 12:30:20 +0530749 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000750 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
751 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
752 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
753 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000755}
756
dbainbri4d3a0dc2020-12-02 00:33:42 +0000757func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
758 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000759
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000761 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000763 return
764 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000765 dh.pOnuTP.lockTpProcMutex()
766 defer dh.pOnuTP.unlockTpProcMutex()
767
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000768 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000770 log.Fields{"device-id": dh.deviceID})
771 dh.reconciling = false
772 return
773 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000774 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000775 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
776 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000778 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
779 dh.reconciling = false
780 return
781 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800782 for tpID := range uniData.PersTpPathMap {
783 // deadline context to ensure completion of background routines waited for
784 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
785 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000786 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000787
Girish Gowdra041dcb32020-11-16 16:54:30 -0800788 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
789 var wg sync.WaitGroup
790 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
792 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800793 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800795 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000796 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000797 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000799 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
800 dh.reconciling = false
801 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000802 }
803}
804
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
806 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000807
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000811 return
812 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000813 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000815 log.Fields{"device-id": dh.deviceID})
816 dh.reconciling = false
817 return
818 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000819 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000820 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
821 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000823 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
824 dh.reconciling = false
825 return
826 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 var uniPort *onuUniPort
828 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000830 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000831 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 return
833 }
834 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000836 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000837 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000839 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
840 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000842 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000845 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000846 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 }
849 }
850 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000851 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000853 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
854 dh.reconciling = false
855 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 }
857}
858
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
860 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 +0000861
862 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000863 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000864}
865
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
867 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000868
dbainbri4d3a0dc2020-12-02 00:33:42 +0000869 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000871 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000873 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000874 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875 pDevEntry.lockOnuKVStoreMutex()
876 defer pDevEntry.unlockOnuKVStoreMutex()
877
878 // deadline context to ensure completion of background routines waited for
879 //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 +0530880 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882
883 pDevEntry.resetKvProcessingErrorIndication()
884
885 var wg sync.WaitGroup
886 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000887 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
888 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000889
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000890 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000891 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000892}
893
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
895 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300896 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000897 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300899 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530901 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530903 return err
904 }
mpagenko01e726e2020-10-23 09:45:29 +0000905
906 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000907 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000908
dbainbri4d3a0dc2020-12-02 00:33:42 +0000909 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000910 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300912 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000913 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000914 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300915 return err
916 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300918 return err
919 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000920 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000921 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
922 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
923 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
924 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300925 return nil
926}
927
mpagenkoc8bba412021-01-15 15:38:44 +0000928//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
929func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
930 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
931 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000932 //return success to comfort the core processing during integration
933 return nil
934 // TODO!!: also verify error response behavior
935 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000936}
937
Himani Chawla6d2ae152020-09-02 13:11:20 +0530938// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000939// #####################################################################################
940
941// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530942// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000943
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
945 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 +0000946}
947
948// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000950
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000952 var err error
953
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000954 // populate what we know. rest comes later after mib sync
955 dh.device.Root = false
956 dh.device.Vendor = "OpenONU"
957 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000958 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000959 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000960
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000961 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000962
963 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
965 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530966 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000967 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000968 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000969 log.Fields{"device-id": dh.deviceID})
970 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000971
Himani Chawla4d908332020-08-31 12:30:20 +0530972 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000973 dh.ponPortNumber = dh.device.ParentPortNo
974
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000975 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
976 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
977 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000979 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530980 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981
982 /*
983 self._pon = PonPort.create(self, self._pon_port_number)
984 self._pon.add_peer(self.parent_id, self._pon_port_number)
985 self.logger.debug('adding-pon-port-to-agent',
986 type=self._pon.get_port().type,
987 admin_state=self._pon.get_port().admin_state,
988 oper_status=self._pon.get_port().oper_status,
989 )
990 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000991 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000993 var ponPortNo uint32 = 1
994 if dh.ponPortNumber != 0 {
995 ponPortNo = dh.ponPortNumber
996 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000998 pPonPort := &voltha.Port{
999 PortNo: ponPortNo,
1000 Label: fmt.Sprintf("pon-%d", ponPortNo),
1001 Type: voltha.Port_PON_ONU,
1002 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301003 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001004 PortNo: ponPortNo}}, // Peer port is parent's port number
1005 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1007 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001008 e.Cancel(err)
1009 return
1010 }
1011 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001013 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001015}
1016
1017// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001018func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001019
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001021 var err error
1022 /*
1023 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1024 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1025 return nil
1026 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1028 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001029 e.Cancel(err)
1030 return
1031 }
1032
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001033 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001034 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001035 // reconcilement will be continued after mib download is done
1036 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001037
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001038 /*
1039 ############################################################################
1040 # Setup Alarm handler
1041 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1042 device.serial_number)
1043 ############################################################################
1044 # Setup PM configuration for this device
1045 # Pass in ONU specific options
1046 kwargs = {
1047 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1048 'heartbeat': self.heartbeat,
1049 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1050 }
1051 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1052 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1053 self.logical_device_id, device.serial_number,
1054 grouped=True, freq_override=False, **kwargs)
1055 pm_config = self._pm_metrics.make_proto()
1056 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1057 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1058 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1059
1060 # Note, ONU ID and UNI intf set in add_uni_port method
1061 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1062 ani_ports=[self._pon])
1063
1064 # Code to Run OMCI Test Action
1065 kwargs_omci_test_action = {
1066 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1067 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1068 }
1069 serial_number = device.serial_number
1070 self._test_request = OmciTestRequest(self.core_proxy,
1071 self.omci_agent, self.device_id,
1072 AniG, serial_number,
1073 self.logical_device_id,
1074 exclusive=False,
1075 **kwargs_omci_test_action)
1076
1077 self.enabled = True
1078 else:
1079 self.logger.info('onu-already-activated')
1080 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001081
dbainbri4d3a0dc2020-12-02 00:33:42 +00001082 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001083}
1084
1085// doStateConnected get the device info and update to voltha core
1086// for comparison of the original method (not that easy to uncomment): compare here:
1087// voltha-openolt-adapter/adaptercore/device_handler.go
1088// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301092 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001093 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001094 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001095}
1096
1097// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001098func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001099
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301101 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001102 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001104
1105 /*
1106 // Synchronous call to update device state - this method is run in its own go routine
1107 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1108 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001109 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 +00001110 return err
1111 }
1112 return nil
1113 */
1114}
1115
1116// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001117func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001118
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001120 var err error
1121
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001122 device := dh.device
1123 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001126 e.Cancel(err)
1127 return
1128 }
1129
1130 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132 /*
1133 // Update the all ports state on that device to disable
1134 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001135 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001136 return er
1137 }
1138
1139 //Update the device oper state and connection status
1140 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1141 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1142 dh.device = cloned
1143
1144 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001145 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146 return er
1147 }
1148
1149 //get the child device for the parent device
1150 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1151 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001152 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001153 return err
1154 }
1155 for _, onuDevice := range onuDevices.Items {
1156
1157 // Update onu state as down in onu adapter
1158 onuInd := oop.OnuIndication{}
1159 onuInd.OperState = "down"
1160 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1161 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1162 if er != nil {
1163 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001164 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001165 //Do not return here and continue to process other ONUs
1166 }
1167 }
1168 // * Discovered ONUs entries need to be cleared , since after OLT
1169 // is up, it starts sending discovery indications again* /
1170 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001171 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001172 return nil
1173 */
Himani Chawla4d908332020-08-31 12:30:20 +05301174 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001175 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001177}
1178
Himani Chawla6d2ae152020-09-02 13:11:20 +05301179// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001180// #################################################################################
1181
1182// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301183// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001184
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001185//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001186func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001187 dh.lockDevice.RLock()
1188 pOnuDeviceEntry := dh.pOnuOmciDevice
1189 if aWait && pOnuDeviceEntry == nil {
1190 //keep the read sema short to allow for subsequent write
1191 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001192 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001193 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1194 // so it might be needed to wait here for that event with some timeout
1195 select {
1196 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001197 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001198 return nil
1199 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001201 // if written now, we can return the written value without sema
1202 return dh.pOnuOmciDevice
1203 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001204 }
mpagenko3af1f032020-06-10 08:53:41 +00001205 dh.lockDevice.RUnlock()
1206 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001207}
1208
Himani Chawla6d2ae152020-09-02 13:11:20 +05301209//setOnuDeviceEntry sets the ONU device entry within the handler
1210func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001211 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001212 dh.lockDevice.Lock()
1213 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001214 dh.pOnuOmciDevice = apDeviceEntry
1215 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001216 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001217}
1218
Himani Chawla6d2ae152020-09-02 13:11:20 +05301219//addOnuDeviceEntry creates a new ONU device or returns the existing
1220func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001221 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001222
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001224 if deviceEntry == nil {
1225 /* costum_me_map in python code seems always to be None,
1226 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1227 /* also no 'clock' argument - usage open ...*/
1228 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001229 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001230 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001231 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001232 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001233 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001234 // fire deviceEntry ready event to spread to possibly waiting processing
1235 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001237 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001239 }
1240 // might be updated with some error handling !!!
1241 return nil
1242}
1243
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1245 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001246 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1247
1248 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001249
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001251 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001253 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1254 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001255 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 if err := dh.storePersistentData(ctx); err != nil {
1257 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001258 log.Fields{"device-id": dh.deviceID, "err": err})
1259 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001261 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001263 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1264 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001266 }
1267 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001269 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001270
1271 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 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 +00001273 log.Fields{"device-id": dh.deviceID})
1274 dh.reconciling = false
1275 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001276 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001277 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1278 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1279 // 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 +00001280 // 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 +00001281 // so let's just try to keep it simple ...
1282 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001284 if err != nil || device == nil {
1285 //TODO: needs to handle error scenarios
1286 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1287 return errors.New("Voltha Device not found")
1288 }
1289 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001290
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001292 return err
mpagenko3af1f032020-06-10 08:53:41 +00001293 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001294
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001296
1297 /* this might be a good time for Omci Verify message? */
1298 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001299 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001300 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001301 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001302 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001303
1304 /* give the handler some time here to wait for the OMCi verification result
1305 after Timeout start and try MibUpload FSM anyway
1306 (to prevent stopping on just not supported OMCI verification from ONU) */
1307 select {
1308 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001309 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001310 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001311 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001312 }
1313
1314 /* In py code it looks earlier (on activate ..)
1315 # Code to Run OMCI Test Action
1316 kwargs_omci_test_action = {
1317 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1318 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1319 }
1320 serial_number = device.serial_number
1321 self._test_request = OmciTestRequest(self.core_proxy,
1322 self.omci_agent, self.device_id,
1323 AniG, serial_number,
1324 self.logical_device_id,
1325 exclusive=False,
1326 **kwargs_omci_test_action)
1327 ...
1328 # Start test requests after a brief pause
1329 if not self._test_request_started:
1330 self._test_request_started = True
1331 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1332 reactor.callLater(tststart, self._test_request.start_collector)
1333
1334 */
1335 /* which is then: in omci_test_request.py : */
1336 /*
1337 def start_collector(self, callback=None):
1338 """
1339 Start the collection loop for an adapter if the frequency > 0
1340
1341 :param callback: (callable) Function to call to collect PM data
1342 """
1343 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1344 if callback is None:
1345 callback = self.perform_test_omci
1346
1347 if self.lc is None:
1348 self.lc = LoopingCall(callback)
1349
1350 if self.default_freq > 0:
1351 self.lc.start(interval=self.default_freq / 10)
1352
1353 def perform_test_omci(self):
1354 """
1355 Perform the initial test request
1356 """
1357 ani_g_entities = self._device.configuration.ani_g_entities
1358 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1359 is not None else None
1360 self._entity_id = ani_g_entities_ids[0]
1361 self.logger.info('perform-test', entity_class=self._entity_class,
1362 entity_id=self._entity_id)
1363 try:
1364 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1365 result = yield self._device.omci_cc.send(frame)
1366 if not result.fields['omci_message'].fields['success_code']:
1367 self.logger.info('Self-Test Submitted Successfully',
1368 code=result.fields[
1369 'omci_message'].fields['success_code'])
1370 else:
1371 raise TestFailure('Test Failure: {}'.format(
1372 result.fields['omci_message'].fields['success_code']))
1373 except TimeoutError as e:
1374 self.deferred.errback(failure.Failure(e))
1375
1376 except Exception as e:
1377 self.logger.exception('perform-test-Error', e=e,
1378 class_id=self._entity_class,
1379 entity_id=self._entity_id)
1380 self.deferred.errback(failure.Failure(e))
1381
1382 */
1383
1384 // PM related heartbeat??? !!!TODO....
1385 //self._heartbeat.enabled = True
1386
mpagenko1cc3cb42020-07-27 15:24:38 +00001387 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1388 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1389 * 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 +05301390 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001391 */
1392 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001393 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001394 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001395 if pMibUlFsm.Is(ulStDisabled) {
1396 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397 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 +00001398 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301399 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301401 //Determine ONU status and start/re-start MIB Synchronization tasks
1402 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001403 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301404 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001405 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 +00001406 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001407 }
Himani Chawla4d908332020-08-31 12:30:20 +05301408 } else {
1409 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410 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 +00001411 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301412 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001414 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001415 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001416 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001417 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001418 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001419 }
1420 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001422 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001423 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001424
1425 // Start PM collector routine
1426 go dh.startCollector(ctx)
1427
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001428 return nil
1429}
1430
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001432 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001433 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001434 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001436
mpagenko900ee4b2020-10-12 11:56:34 +00001437 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1438 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1439 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001440 if err := dh.resetFsms(ctx); err != nil {
1441 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001442 log.Fields{"device-id": dh.deviceID, "error": err})
1443 // abort: system behavior is just unstable ...
1444 return err
1445 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001446 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 _ = 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 +00001448
1449 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1450 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1451 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001452 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001453 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001454 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001455 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001456 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001458
1459 //TODO!!! remove existing traffic profiles
1460 /* from py code, if TP's exist, remove them - not yet implemented
1461 self._tp = dict()
1462 # Let TP download happen again
1463 for uni_id in self._tp_service_specific_task:
1464 self._tp_service_specific_task[uni_id].clear()
1465 for uni_id in self._tech_profile_download_done:
1466 self._tech_profile_download_done[uni_id].clear()
1467 */
1468
dbainbri4d3a0dc2020-12-02 00:33:42 +00001469 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001470
mpagenkofc4f56e2020-11-04 17:17:49 +00001471 dh.ReadyForSpecificOmciConfig = false
1472
dbainbri4d3a0dc2020-12-02 00:33:42 +00001473 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001474 // abort: system behavior is just unstable ...
1475 return err
1476 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001478 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001480 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001481 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001483 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001484 // abort: system behavior is just unstable ...
1485 return err
1486 }
1487 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001488 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001489 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001490 return nil
1491}
1492
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001494 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1495 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1496 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1497 // and using the stop/reset event should never harm
1498
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001500 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001502 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1503 }
mpagenko900ee4b2020-10-12 11:56:34 +00001504 //the MibSync FSM might be active all the ONU-active time,
1505 // hence it must be stopped unconditionally
1506 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1507 if pMibUlFsm != nil {
1508 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1509 }
1510 //MibDownload may run
1511 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1512 if pMibDlFsm != nil {
1513 _ = pMibDlFsm.Event(dlEvReset)
1514 }
1515 //port lock/unlock FSM's may be active
1516 if dh.pUnlockStateFsm != nil {
1517 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1518 }
1519 if dh.pLockStateFsm != nil {
1520 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1521 }
1522 //techProfile related PonAniConfigFsm FSM may be active
1523 if dh.pOnuTP != nil {
1524 // should always be the case here
1525 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1526 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001527 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1528 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1529 }
mpagenko900ee4b2020-10-12 11:56:34 +00001530 }
1531 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001532 // reset the possibly existing VlanConfigFsm
1533 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1534 //VlanFilterFsm exists and was already started
1535 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1536 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001537 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001538 // no need to remove specific data
1539 pVlanFilterFsm.RequestClearPersistency(false)
1540 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001541 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1542 }
1543 }
1544 }
1545 }
Girish Gowdraaf0ad632021-01-27 13:00:01 -08001546
1547 // Stop collector routine
Girish Gowdrae09a6202021-01-12 18:10:59 -08001548 dh.stopCollector <- true
1549
mpagenko900ee4b2020-10-12 11:56:34 +00001550 return nil
1551}
1552
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1554 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 +05301555
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1557 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001558 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001560 return
1561 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001562 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001563 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1564 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1565 for _, mgmtEntityID := range pptpInstKeys {
1566 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1567 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301569 i++
1570 }
1571 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301573 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001574 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1575 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301576 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001577 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301578 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301580 i++
1581 }
1582 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301584 }
1585 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301587 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001588 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1589 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1590 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1591 * disable/enable toggling here to allow traffic
1592 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1593 * like the py comment says:
1594 * # start by locking all the unis till mib sync and initial mib is downloaded
1595 * # this way we can capture the port down/up events when we are ready
1596 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301597
mpagenkoa40e99a2020-11-17 13:50:39 +00001598 // Init Uni Ports to Admin locked state
1599 // *** should generate UniLockStateDone event *****
1600 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001602 } else { //LockStateFSM already init
1603 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001605 }
1606}
1607
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1609 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301610 /* Mib download procedure -
1611 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1612 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001614 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001616 return
1617 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301618 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1619 if pMibDlFsm != nil {
1620 if pMibDlFsm.Is(dlStDisabled) {
1621 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 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 +05301623 // maybe try a FSM reset and then again ... - TODO!!!
1624 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301626 // maybe use more specific states here for the specific download steps ...
1627 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301629 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301631 //Begin MIB data download (running autonomously)
1632 }
1633 }
1634 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001636 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301637 // maybe try a FSM reset and then again ... - TODO!!!
1638 }
1639 /***** Mib download started */
1640 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301642 }
1643}
1644
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1646 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301647 //initiate DevStateUpdate
1648 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001650 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301652 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1653 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301657 }
1658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001660 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001662 return
1663 }
1664 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 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 +00001666 log.Fields{"device-id": dh.deviceID})
1667 dh.reconciling = false
1668 return
1669 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301671 log.Fields{"device-id": dh.deviceID})
1672 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001674 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301675 // *** should generate UniUnlockStateDone event *****
1676 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301678 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301679 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301681 }
1682}
1683
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1685 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301686
1687 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301689 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1691 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001692 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 return
1695 }
1696 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 if err := dh.storePersistentData(ctx); err != nil {
1698 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001699 log.Fields{"device-id": dh.deviceID, "err": err})
1700 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301701 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 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 +05301703 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001705 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301706 }
1707}
1708
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1710 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001711 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001713 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1714 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001716 }
1717
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001719 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001721
1722 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001728 return
1729 }
1730 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 if err := dh.storePersistentData(ctx); err != nil {
1732 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001733 log.Fields{"device-id": dh.deviceID, "err": err})
1734 }
mpagenko900ee4b2020-10-12 11:56:34 +00001735}
1736
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1738 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001739 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001740 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001741 voltha.OperStatus_ACTIVE); err != nil {
1742 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001744 }
1745
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001747 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001748 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001750
1751 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001753
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001755 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001757 return
1758 }
1759 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 if err := dh.storePersistentData(ctx); err != nil {
1761 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001762 log.Fields{"device-id": dh.deviceID, "err": err})
1763 }
mpagenko900ee4b2020-10-12 11:56:34 +00001764}
1765
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001767 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001769 // attention: the device reason update is done based on ONU-UNI-Port related activity
1770 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001771 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001772 // 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 +00001773 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301774 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001775 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001777 }
1778 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001780 // attention: the device reason update is done based on ONU-UNI-Port related activity
1781 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001782 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001783 // 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 +00001784 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001785 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001786 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301787}
1788
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1790 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001791 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301792 // attention: the device reason update is done based on ONU-UNI-Port related activity
1793 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301794
mpagenkofc4f56e2020-11-04 17:17:49 +00001795 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001796 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001797 // which may be the case from some previous actvity on another UNI Port of the ONU
1798 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001800 // request MDS-value for test and logging purposes
1801 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001802 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001804 }
1805 }
1806 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001807 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001808 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001809 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001810 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301811 }
1812}
1813
Himani Chawla6d2ae152020-09-02 13:11:20 +05301814//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301816 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001817 case MibDatabaseSync:
1818 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001819 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001820 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001821 case UniLockStateDone:
1822 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001824 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001825 case MibDownloadDone:
1826 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001828 }
1829 case UniUnlockStateDone:
1830 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001832 }
mpagenko900ee4b2020-10-12 11:56:34 +00001833 case UniEnableStateDone:
1834 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001836 }
1837 case UniDisableStateDone:
1838 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001840 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001841 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001842 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001844 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001845 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001846 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001848 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001849 default:
1850 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001852 }
1853 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001854}
1855
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001857 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001858 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301859 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001860 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301863 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001865 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001867 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001868 //store UniPort with the System-PortNumber key
1869 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001870 if !dh.reconciling {
1871 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1873 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001874 } //error logging already within UniPort method
1875 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001877 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001878 }
1879 }
1880}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001881
mpagenko3af1f032020-06-10 08:53:41 +00001882// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001884 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301885 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001886 // with following remark:
1887 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1888 // # load on the core
1889
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001890 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001891
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001892 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001893 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301894 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301896 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001897 if !dh.reconciling {
1898 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 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 +00001900 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001901 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001903 }
mpagenko3af1f032020-06-10 08:53:41 +00001904 }
1905 }
1906}
1907
1908// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001909func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001910 // compare enableUniPortStateUpdate() above
1911 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1912 for uniNo, uniPort := range dh.uniEntityMap {
1913 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301914 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001915 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301916 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001917 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918 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 +00001919 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001920 }
1921}
1922
1923// ONU_Active/Inactive announcement on system KAFKA bus
1924// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001926 var de voltha.DeviceEvent
1927 eventContext := make(map[string]string)
1928 //Populating event context
1929 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001931 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301933 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001934 }
1935 oltSerialNumber := parentDevice.SerialNumber
1936
1937 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1938 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1939 eventContext["serial-number"] = dh.device.SerialNumber
1940 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301941 eventContext["device_id"] = aDeviceID
1942 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001944 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001945
1946 /* Populating device event body */
1947 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301948 de.ResourceId = aDeviceID
1949 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001950 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1951 de.Description = fmt.Sprintf("%s Event - %s - %s",
1952 cEventObjectType, cOnuActivatedEvent, "Raised")
1953 } else {
1954 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1955 de.Description = fmt.Sprintf("%s Event - %s - %s",
1956 cEventObjectType, cOnuActivatedEvent, "Cleared")
1957 }
1958 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1960 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301961 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001962 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301964 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001965}
1966
Himani Chawla4d908332020-08-31 12:30:20 +05301967// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001969 chLSFsm := make(chan Message, 2048)
1970 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301971 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001973 sFsmName = "LockStateFSM"
1974 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001976 sFsmName = "UnLockStateFSM"
1977 }
mpagenko3af1f032020-06-10 08:53:41 +00001978
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001980 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001982 return
1983 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001985 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001986 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301987 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001988 dh.pLockStateFsm = pLSFsm
1989 } else {
1990 dh.pUnlockStateFsm = pLSFsm
1991 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001993 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001995 }
1996}
1997
1998// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002000 /* Uni Port lock/unlock procedure -
2001 ***** should run via 'adminDone' state and generate the argument requested event *****
2002 */
2003 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302004 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002005 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2006 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2007 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002008 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302009 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002010 }
2011 } else {
2012 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2013 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2014 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002015 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302016 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002017 }
2018 }
2019 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002020 if pLSStatemachine.Is(uniStDisabled) {
2021 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002023 // maybe try a FSM reset and then again ... - TODO!!!
2024 } else {
2025 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002027 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002028 }
2029 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002030 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002031 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002032 // maybe try a FSM reset and then again ... - TODO!!!
2033 }
2034 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002036 // maybe try a FSM reset and then again ... - TODO!!!
2037 }
2038}
2039
Himani Chawla6d2ae152020-09-02 13:11:20 +05302040//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002042 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002044 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002045 kvbackend := &db.Backend{
2046 Client: dh.pOpenOnuAc.kvClient,
2047 StoreType: dh.pOpenOnuAc.KVStoreType,
2048 /* address config update acc. to [VOL-2736] */
2049 Address: addr,
2050 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2051 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002052
mpagenkoaf801632020-07-03 10:00:42 +00002053 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002054}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302056 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002057
mpagenkodff5dda2020-08-28 11:52:01 +00002058 for _, field := range flow.GetOfbFields(apFlowItem) {
2059 switch field.Type {
2060 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2061 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002063 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2064 }
mpagenko01e726e2020-10-23 09:45:29 +00002065 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002066 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2067 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302068 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002069 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302070 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2071 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002072 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2073 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002074 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2075 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302076 return
mpagenkodff5dda2020-08-28 11:52:01 +00002077 }
2078 }
mpagenko01e726e2020-10-23 09:45:29 +00002079 */
mpagenkodff5dda2020-08-28 11:52:01 +00002080 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2081 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302082 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002083 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302084 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002085 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302086 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002087 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002088 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302089 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002090 }
2091 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2092 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302093 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002094 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002095 "PCP": loAddPcp})
2096 }
2097 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2098 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002099 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002100 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2101 }
2102 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2103 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002105 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2106 }
2107 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2108 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002110 "IPv4-DST": field.GetIpv4Dst()})
2111 }
2112 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2113 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002115 "IPv4-SRC": field.GetIpv4Src()})
2116 }
2117 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2118 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002120 "Metadata": field.GetTableMetadata()})
2121 }
2122 /*
2123 default:
2124 {
2125 //all other entires ignored
2126 }
2127 */
2128 }
2129 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302130}
mpagenkodff5dda2020-08-28 11:52:01 +00002131
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002133 for _, action := range flow.GetActions(apFlowItem) {
2134 switch action.Type {
2135 /* not used:
2136 case of.OfpActionType_OFPAT_OUTPUT:
2137 {
mpagenko01e726e2020-10-23 09:45:29 +00002138 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002139 "Output": action.GetOutput()})
2140 }
2141 */
2142 case of.OfpActionType_OFPAT_PUSH_VLAN:
2143 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002145 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2146 }
2147 case of.OfpActionType_OFPAT_SET_FIELD:
2148 {
2149 pActionSetField := action.GetSetField()
2150 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002152 "OxcmClass": pActionSetField.Field.OxmClass})
2153 }
2154 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302155 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002158 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302159 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302161 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002162 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002164 "Type": pActionSetField.Field.GetOfbField().Type})
2165 }
2166 }
2167 /*
2168 default:
2169 {
2170 //all other entires ignored
2171 }
2172 */
2173 }
2174 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302175}
2176
2177//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302179 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2180 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2181 var loAddPcp, loSetPcp uint8
2182 var loIPProto uint32
2183 /* the TechProfileId is part of the flow Metadata - compare also comment within
2184 * OLT-Adapter:openolt_flowmgr.go
2185 * Metadata 8 bytes:
2186 * Most Significant 2 Bytes = Inner VLAN
2187 * Next 2 Bytes = Tech Profile ID(TPID)
2188 * Least Significant 4 Bytes = Port ID
2189 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2190 * subscriber related flows.
2191 */
2192
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302194 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302196 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002197 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302198 }
mpagenko551a4d42020-12-08 18:09:20 +00002199 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002200 loCookie := apFlowItem.GetCookie()
2201 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002203 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302204
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002206 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302207 if loIPProto == 2 {
2208 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2209 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002210 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2211 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302212 return nil
2213 }
mpagenko01e726e2020-10-23 09:45:29 +00002214 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002216
2217 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002219 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2220 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2221 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2222 //TODO!!: Use DeviceId within the error response to rwCore
2223 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002224 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002225 }
2226 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002228 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2229 } else {
2230 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2231 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2232 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302233 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002234 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002235 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002236 }
mpagenko9a304ea2020-12-16 15:54:01 +00002237
2238 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2239 dh.lockVlanConfig.Lock()
2240 defer dh.lockVlanConfig.Unlock()
2241 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302242 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002243 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002244 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002245 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002247 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002248}
2249
2250//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002251func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002252 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2253 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2254 //no extra check is done on the rule parameters
2255 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2256 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2257 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2258 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002259 // - 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 +00002260 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002262
2263 /* TT related temporary workaround - should not be needed anymore
2264 for _, field := range flow.GetOfbFields(apFlowItem) {
2265 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2266 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002267 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002268 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2269 if loIPProto == 2 {
2270 // 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 +00002271 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002272 log.Fields{"device-id": dh.deviceID})
2273 return nil
2274 }
2275 }
2276 } //for all OfbFields
2277 */
2278
mpagenko9a304ea2020-12-16 15:54:01 +00002279 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2280 dh.lockVlanConfig.Lock()
2281 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002282 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002283 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002284 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002286 log.Fields{"device-id": dh.deviceID})
2287 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002288 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002290
mpagenko01e726e2020-10-23 09:45:29 +00002291 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002292}
2293
Himani Chawla26e555c2020-08-31 12:30:20 +05302294// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002295// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002296func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002297 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002298 chVlanFilterFsm := make(chan Message, 2048)
2299
dbainbri4d3a0dc2020-12-02 00:33:42 +00002300 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002301 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302303 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002304 }
2305
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002307 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2308 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002309 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302310 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002311 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2312 if pVlanFilterStatemachine != nil {
2313 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2314 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302316 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002317 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302318 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302320 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2321 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002322 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002324 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302325 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002326 }
2327 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002329 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302330 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002331 }
2332 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002334 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302335 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002336 }
2337 return nil
2338}
2339
mpagenkofc4f56e2020-11-04 17:17:49 +00002340//VerifyVlanConfigRequest checks on existence of a given uniPort
2341// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002342func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002343 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2344 var pCurrentUniPort *onuUniPort
2345 for _, uniPort := range dh.uniEntityMap {
2346 // only if this port is validated for operState transfer
2347 if uniPort.uniID == uint8(aUniID) {
2348 pCurrentUniPort = uniPort
2349 break //found - end search loop
2350 }
2351 }
2352 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002354 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2355 return
2356 }
mpagenko551a4d42020-12-08 18:09:20 +00002357 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002358}
2359
mpagenkodff5dda2020-08-28 11:52:01 +00002360//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002361func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002362 //TODO!! verify and start pending flow configuration
2363 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2364 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302365 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002366 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2367 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2368 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002369 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2370 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2371 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2372 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2373 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2374 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2375 } else {
2376 /***** UniVlanConfigFsm continued */
2377 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2378 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2379 "UniPort": apUniPort.portNo})
2380 }
2381 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2382 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2383 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2384 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2385 } else {
2386 /***** UniVlanConfigFsm continued */
2387 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2388 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2389 "UniPort": apUniPort.portNo})
2390 }
mpagenkodff5dda2020-08-28 11:52:01 +00002391 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002392 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2393 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002394 "UniPort": apUniPort.portNo})
2395 }
2396 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002397 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2398 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2399 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002400 }
2401 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002402 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002403 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002404 }
mpagenkodff5dda2020-08-28 11:52:01 +00002405 } // else: nothing to do
2406}
2407
2408//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2409// 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 +00002410func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2411 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002412 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2413 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302414 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002415}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002416
2417//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2418//available for potential reconcilement
2419
dbainbri4d3a0dc2020-12-02 00:33:42 +00002420func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002421
2422 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002424 return nil
2425 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002427
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002429 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002431 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2432 }
2433 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2434
2435 pDevEntry.lockOnuKVStoreMutex()
2436 defer pDevEntry.unlockOnuKVStoreMutex()
2437
2438 // deadline context to ensure completion of background routines waited for
2439 //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 +05302440 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002441 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2442
2443 pDevEntry.resetKvProcessingErrorIndication()
2444 var wg sync.WaitGroup
2445 wg.Add(1) // for the 1 go routine to finish
2446
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2448 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002449
2450 return pDevEntry.getKvProcessingErrorIndication()
2451}
2452
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002454 defer cancel() //ensure termination of context (may be pro forma)
2455 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002456 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002457 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002458}
2459
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002461
2462 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002463 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002464 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2466 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002467 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002468 return err
2469 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002470 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002471 return nil
2472 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002474 return nil
2475}
2476
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2478 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002479 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002480 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002481 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2482 }
2483 pDevEntry.lockOnuKVStoreMutex()
2484 defer pDevEntry.unlockOnuKVStoreMutex()
2485
2486 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2487 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2488
2489 pDevEntry.resetKvProcessingErrorIndication()
2490 var wg sync.WaitGroup
2491 wg.Add(1) // for the 1 go routine to finish
2492
2493 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002495
2496 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002498 return err
2499 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002500 return nil
2501}
2502
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002503func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2504 var errStr string = ""
2505 for _, err := range errS {
2506 if err != nil {
2507 errStr = errStr + err.Error() + " "
2508 }
2509 }
2510 if errStr != "" {
2511 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2512 }
2513 return nil
2514}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002515
2516// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2517func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2518 dh.lockDevice.RLock()
2519 defer dh.lockDevice.RUnlock()
2520 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2521 return uniPort.entityID, nil
2522 }
2523 return 0, errors.New("error-fetching-uni-port")
2524}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002525
2526// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002527func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2528 var errorsList []error
2529 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 -08002530
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002531 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2532 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2533 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2534
2535 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2536 // successfully.
2537 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2538 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2539 if len(errorsList) > 0 {
2540 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2541 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002542 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002543 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2544 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002545}
2546
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002547func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2548 var err error
2549 var errorsList []error
2550 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2551
2552 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2553 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2554 errorsList = append(errorsList, err)
2555 }
2556 }
2557
2558 return errorsList
2559}
2560
2561func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2562 var err error
2563 var errorsList []error
2564 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2565 // Check if group metric related config is updated
2566 for _, v := range pmConfigs.Groups {
2567 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2568 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2569 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2570
2571 if ok && m.frequency != v.GroupFreq {
2572 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2573 errorsList = append(errorsList, err)
2574 }
2575 }
2576 if ok && m.enabled != v.Enabled {
2577 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2578 errorsList = append(errorsList, err)
2579 }
2580 }
2581 }
2582 return errorsList
2583}
2584
2585func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2586 var err error
2587 var errorsList []error
2588 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2589 // Check if standalone metric related config is updated
2590 for _, v := range pmConfigs.Metrics {
2591 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002592 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002593 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2594
2595 if ok && m.frequency != v.SampleFreq {
2596 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2597 errorsList = append(errorsList, err)
2598 }
2599 }
2600 if ok && m.enabled != v.Enabled {
2601 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2602 errorsList = append(errorsList, err)
2603 }
2604 }
2605 }
2606 return errorsList
2607}
2608
2609// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002610func (dh *deviceHandler) startCollector(ctx context.Context) {
2611 logger.Debugf(ctx, "startingCollector")
2612
2613 // Start routine to process OMCI GET Responses
2614 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002615 // Initialize the next metric collection time.
2616 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2617 // reset like onu rebooted.
2618 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002619 for {
2620 select {
2621 case <-dh.stopCollector:
2622 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2623 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2624 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002625 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2626 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2627 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2628 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2629 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002630 // Update the next metric collection time.
2631 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002632 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002633 } else {
2634 if dh.pmConfigs.Grouped { // metrics are managed as a group
2635 // parse through the group and standalone metrics to see it is time to collect their metrics
2636 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002637
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002638 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2639 // If the group is enabled AND (current time is equal to OR after nextCollectionInterval, collect the group metric)
2640 if g.enabled && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
2641 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2642 }
2643 }
2644 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2645 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2646 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2647 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2648 }
2649 }
2650 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2651
2652 // parse through the group and update the next metric collection time
2653 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2654 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2655 // If group enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2656 if g.enabled && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
2657 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2658 }
2659 }
2660 // parse through the standalone metrics and update the next metric collection time
2661 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2662 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2663 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2664 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2665 }
2666 }
2667 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2668 } /* else { // metrics are not managed as a group
2669 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2670 } */
2671 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002672 }
2673 }
2674}