blob: 758bf9ede68ebd4f7d6395d13c10d7259c6b0733 [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"
Girish Gowdrae09a6202021-01-12 18:10:59 -080034 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/common"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053036 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000037 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
38 "github.com/opencord/voltha-lib-go/v4/pkg/log"
39 vc "github.com/opencord/voltha-protos/v4/go/common"
40 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
41 "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v4/go/openolt"
45 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000046)
47
48/*
49// Constants for number of retries and for timeout
50const (
51 MaxRetry = 10
52 MaxTimeOutInMs = 500
53)
54*/
55
mpagenko1cc3cb42020-07-27 15:24:38 +000056const (
57 // events of Device FSM
58 devEvDeviceInit = "devEvDeviceInit"
59 devEvGrpcConnected = "devEvGrpcConnected"
60 devEvGrpcDisconnected = "devEvGrpcDisconnected"
61 devEvDeviceUpInd = "devEvDeviceUpInd"
62 devEvDeviceDownInd = "devEvDeviceDownInd"
63)
64const (
65 // states of Device FSM
66 devStNull = "devStNull"
67 devStDown = "devStDown"
68 devStInit = "devStInit"
69 devStConnected = "devStConnected"
70 devStUp = "devStUp"
71)
72
Holger Hildebrandt24d51952020-05-04 14:03:42 +000073//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
74const (
Himani Chawla4d908332020-08-31 12:30:20 +053075 pon = voltha.EventSubCategory_PON
76 //olt = voltha.EventSubCategory_OLT
77 //ont = voltha.EventSubCategory_ONT
78 //onu = voltha.EventSubCategory_ONU
79 //nni = voltha.EventSubCategory_NNI
80 //service = voltha.EventCategory_SERVICE
81 //security = voltha.EventCategory_SECURITY
82 equipment = voltha.EventCategory_EQUIPMENT
83 //processing = voltha.EventCategory_PROCESSING
84 //environment = voltha.EventCategory_ENVIRONMENT
85 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000086)
87
88const (
89 cEventObjectType = "ONU"
90)
91const (
92 cOnuActivatedEvent = "ONU_ACTIVATED"
93)
94
Holger Hildebrandt80129db2020-11-23 10:49:32 +000095const (
96 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +000097 drUnset = 0
98 drActivatingOnu = 1
99 drStartingOpenomci = 2
100 drDiscoveryMibsyncComplete = 3
101 drInitialMibDownloaded = 4
102 drTechProfileConfigDownloadSuccess = 5
103 drOmciFlowsPushed = 6
104 drOmciAdminLock = 7
105 drOnuReenabled = 8
106 drStoppingOpenomci = 9
107 drRebooting = 10
108 drOmciFlowsDeleted = 11
109 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000110)
111
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000112var deviceReasonMap = map[uint8]string{
113 drUnset: "unset",
114 drActivatingOnu: "activating-onu",
115 drStartingOpenomci: "starting-openomci",
116 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
117 drInitialMibDownloaded: "initial-mib-downloaded",
118 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
119 drOmciFlowsPushed: "omci-flows-pushed",
120 drOmciAdminLock: "omci-admin-lock",
121 drOnuReenabled: "onu-reenabled",
122 drStoppingOpenomci: "stopping-openomci",
123 drRebooting: "rebooting",
124 drOmciFlowsDeleted: "omci-flows-deleted",
125 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
126}
127
Girish Gowdrae09a6202021-01-12 18:10:59 -0800128// OmciOpticalMetricsNames are supported optical pm names
129var OmciOpticalMetricsNames = map[string]voltha.PmConfig_PmType{
130 "transmit_power": voltha.PmConfig_GAUGE,
131 "receive_power": voltha.PmConfig_GAUGE,
132}
133
134// OmciUniMetricsNames are supported UNI status names
135var OmciUniMetricsNames = map[string]voltha.PmConfig_PmType{
136 "ethernet_type": voltha.PmConfig_GAUGE,
137 "oper_status": voltha.PmConfig_GAUGE,
138 "uni_admin_state": voltha.PmConfig_GAUGE,
139}
140
Himani Chawla6d2ae152020-09-02 13:11:20 +0530141//deviceHandler will interact with the ONU ? device.
142type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000143 deviceID string
144 DeviceType string
145 adminState string
146 device *voltha.Device
147 logicalDeviceID string
148 ProxyAddressID string
149 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530150 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000151 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000153 coreProxy adapterif.CoreProxy
154 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530155 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000156
Girish Gowdrae09a6202021-01-12 18:10:59 -0800157 pmMetrics *common.PmMetrics
158
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000159 pOpenOnuAc *OpenONUAC
160 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530161 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000162 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530164 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800165 pOnuMetricsMgr *onuMetricsManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000166 exitChannel chan int
167 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000168 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000169 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530170 pLockStateFsm *lockStateFsm
171 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000172
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173 //flowMgr *OpenOltFlowMgr
174 //eventMgr *OpenOltEventMgr
175 //resourceMgr *rsrcMgr.OpenOltResourceMgr
176
177 //discOnus sync.Map
178 //onus sync.Map
179 //portStats *OpenOltStatisticsMgr
mpagenkofc4f56e2020-11-04 17:17:49 +0000180 stopCollector chan bool
181 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000182 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000183 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000184 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
185 reconciling bool
186 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187}
188
Himani Chawla6d2ae152020-09-02 13:11:20 +0530189//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530190func 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 +0530191 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000192 dh.coreProxy = cp
193 dh.AdapterProxy = ap
194 dh.EventProxy = ep
195 cloned := (proto.Clone(device)).(*voltha.Device)
196 dh.deviceID = cloned.Id
197 dh.DeviceType = cloned.Type
198 dh.adminState = "up"
199 dh.device = cloned
200 dh.pOpenOnuAc = adapter
201 dh.exitChannel = make(chan int, 1)
202 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000203 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204 dh.stopCollector = make(chan bool, 2)
205 dh.stopHeartbeatCheck = make(chan bool, 2)
206 //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 +0000207 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530208 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000209 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000210 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000211 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000212 dh.ReadyForSpecificOmciConfig = false
Girish Gowdrae09a6202021-01-12 18:10:59 -0800213 metricNames := make([]string, len(OmciOpticalMetricsNames)+len(OmciUniMetricsNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000214
Girish Gowdrae09a6202021-01-12 18:10:59 -0800215 for k := range OmciOpticalMetricsNames {
216 metricNames = append(metricNames, k)
217 }
218
219 for k := range OmciUniMetricsNames {
220 metricNames = append(metricNames, k)
221 }
222
223 // The frequency is in seconds.
224 dh.pmMetrics = common.NewPmMetrics(cloned.Id, common.Frequency(150), common.FrequencyOverride(false), common.Grouped(false), common.Metrics(metricNames))
225 for pmName, pmType := range OmciOpticalMetricsNames {
226 dh.pmMetrics.ToPmConfigs().Metrics = append(dh.pmMetrics.ToPmConfigs().Metrics, &voltha.PmConfig{
227 Name: pmName,
228 Type: pmType,
229 Enabled: true,
230 })
231 }
232 for pmName, pmType := range OmciUniMetricsNames {
233 dh.pmMetrics.ToPmConfigs().Metrics = append(dh.pmMetrics.ToPmConfigs().Metrics, &voltha.PmConfig{
234 Name: pmName,
235 Type: pmType,
236 Enabled: true,
237 })
238 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239 // Device related state machine
240 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000241 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000243 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
244 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
245 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
246 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
247 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 },
249 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000250 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
251 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
252 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
253 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
254 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
255 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
256 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
257 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 },
259 )
mpagenkoaf801632020-07-03 10:00:42 +0000260
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 return &dh
262}
263
Himani Chawla6d2ae152020-09-02 13:11:20 +0530264// start save the device to the data model
265func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000266 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000268 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269}
270
Himani Chawla4d908332020-08-31 12:30:20 +0530271/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530273func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000274 logger.Debug("stopping-device-handler")
275 dh.exitChannel <- 1
276}
Himani Chawla4d908332020-08-31 12:30:20 +0530277*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278
279// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530280// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281
Himani Chawla6d2ae152020-09-02 13:11:20 +0530282//adoptOrReconcileDevice adopts the OLT device
283func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000285
dbainbri4d3a0dc2020-12-02 00:33:42 +0000286 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000287 if dh.pDeviceStateFsm.Is(devStNull) {
288 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000291 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdrae09a6202021-01-12 18:10:59 -0800292 // Now, set the initial PM configuration for that device
293 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmMetrics.ToPmConfigs()); err != nil {
294 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
295 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298 }
299
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300}
301
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302func (dh *deviceHandler) processInterAdapterOMCIReqMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530303 msgBody := msg.GetBody()
304 omciMsg := &ic.InterAdapterOmciMessage{}
305 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530307 "device-id": dh.deviceID, "error": err})
308 return err
309 }
310
311 //assuming omci message content is hex coded!
312 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000313 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530314 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
315 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530317 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000318 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000320 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 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 +0530322 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000323 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000324 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530325}
326
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530329 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000330
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000332
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000334 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000336 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
337 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530338 if dh.pOnuTP == nil {
339 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000340 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530341 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000342 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530343 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000344 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000346 "device-state": deviceReasonMap[dh.deviceReason]})
347 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000349 //previous state test here was just this one, now extended for more states to reject the SetRequest:
350 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
351 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530352
353 msgBody := msg.GetBody()
354 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
355 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 "device-id": dh.deviceID, "error": err})
358 return err
359 }
360
361 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000362 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
363 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530364 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 defer dh.pOnuTP.unlockTpProcMutex()
366 pDevEntry.lockOnuKVStoreMutex()
367 defer pDevEntry.unlockOnuKVStoreMutex()
368
369 if techProfMsg.UniId > 255 {
370 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
371 techProfMsg.UniId, dh.deviceID))
372 }
373 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800374 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
375 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000376 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800377 return err
378 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379
dbainbri4d3a0dc2020-12-02 00:33:42 +0000380 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 // if there has been some change for some uni TechProfilePath
382 //in order to allow concurrent calls to other dh instances we do not wait for execution here
383 //but doing so we can not indicate problems to the caller (who does what with that then?)
384 //by now we just assume straightforward successful execution
385 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
386 // possible problems to the caller later autonomously
387
388 // deadline context to ensure completion of background routines waited for
389 //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 +0530390 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 dctx, cancel := context.WithDeadline(context.Background(), deadline)
392
Girish Gowdra041dcb32020-11-16 16:54:30 -0800393 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394 pDevEntry.resetKvProcessingErrorIndication()
395
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 var wg sync.WaitGroup
397 wg.Add(2) // for the 2 go routines to finish
398 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000399 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
400 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
401 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402
Girish Gowdra041dcb32020-11-16 16:54:30 -0800403 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530406 return nil
407}
408
Himani Chawla6d2ae152020-09-02 13:11:20 +0530409func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000410 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530411 msg *ic.InterAdapterMessage) error {
412
dbainbri4d3a0dc2020-12-02 00:33:42 +0000413 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000414
dbainbri4d3a0dc2020-12-02 00:33:42 +0000415 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000416 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000417 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
419 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530420 if dh.pOnuTP == nil {
421 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000422 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530423 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 }
426
427 msgBody := msg.GetBody()
428 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
429 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000430 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 "device-id": dh.deviceID, "error": err})
432 return err
433 }
434
435 //compare TECH_PROFILE_DOWNLOAD_REQUEST
436 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000437 defer dh.pOnuTP.unlockTpProcMutex()
438 pDevEntry.lockOnuKVStoreMutex()
439 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530440
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441 if delGemPortMsg.UniId > 255 {
442 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
443 delGemPortMsg.UniId, dh.deviceID))
444 }
445 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800446 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
447 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000448 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 -0800449 return err
450 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530451
mpagenkofc4f56e2020-11-04 17:17:49 +0000452 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453
mpagenkofc4f56e2020-11-04 17:17:49 +0000454 // deadline context to ensure completion of background routines waited for
455 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
456 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000457
Girish Gowdra041dcb32020-11-16 16:54:30 -0800458 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459
mpagenkofc4f56e2020-11-04 17:17:49 +0000460 var wg sync.WaitGroup
461 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000462 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000463 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000464 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000465
Girish Gowdra041dcb32020-11-16 16:54:30 -0800466 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530467}
468
Himani Chawla6d2ae152020-09-02 13:11:20 +0530469func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530471 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000472
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000474
dbainbri4d3a0dc2020-12-02 00:33:42 +0000475 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
479 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 if dh.pOnuTP == nil {
481 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 }
486
487 msgBody := msg.GetBody()
488 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
489 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 "device-id": dh.deviceID, "error": err})
492 return err
493 }
494
495 //compare TECH_PROFILE_DOWNLOAD_REQUEST
496 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 defer dh.pOnuTP.unlockTpProcMutex()
498 pDevEntry.lockOnuKVStoreMutex()
499 defer pDevEntry.unlockOnuKVStoreMutex()
500
501 if delTcontMsg.UniId > 255 {
502 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
503 delTcontMsg.UniId, dh.deviceID))
504 }
505 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800506 tpPath := delTcontMsg.TpPath
507 tpID, err := GetTpIDFromTpPath(tpPath)
508 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 return err
511 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000512
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530514 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530515 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530516 dctx, cancel := context.WithDeadline(context.Background(), deadline)
517
Girish Gowdra041dcb32020-11-16 16:54:30 -0800518 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519 pDevEntry.resetKvProcessingErrorIndication()
520
Himani Chawla26e555c2020-08-31 12:30:20 +0530521 var wg sync.WaitGroup
522 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 cResourceTcont, delTcontMsg.AllocId, &wg)
525 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
527 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528
Girish Gowdra041dcb32020-11-16 16:54:30 -0800529 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 return nil
532}
533
Himani Chawla6d2ae152020-09-02 13:11:20 +0530534//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000535// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
536// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000537func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000538 msgID := msg.Header.Id
539 msgType := msg.Header.Type
540 fromTopic := msg.Header.FromTopic
541 toTopic := msg.Header.ToTopic
542 toDeviceID := msg.Header.ToDeviceId
543 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000544 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000545 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
546
547 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000548 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000549 case ic.InterAdapterMessageType_OMCI_REQUEST:
550 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 return dh.processInterAdapterOMCIReqMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000552 }
mpagenkoaf801632020-07-03 10:00:42 +0000553 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
554 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000556 }
557 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
558 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000559 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000560
mpagenkoaf801632020-07-03 10:00:42 +0000561 }
562 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
563 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000565 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000566 default:
567 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000569 "msgType": msg.Header.Type, "device-id": dh.deviceID})
570 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 }
572 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000573}
574
mpagenkodff5dda2020-08-28 11:52:01 +0000575//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
577 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000578 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000580
mpagenko01e726e2020-10-23 09:45:29 +0000581 var retError error = nil
582 //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 +0000583 if apOfFlowChanges.ToRemove != nil {
584 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000585 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000587 "device-id": dh.deviceID})
588 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000589 continue
590 }
591 flowInPort := flow.GetInPort(flowItem)
592 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 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 +0000594 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
595 continue
596 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000597 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000598 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000600 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000601 continue
602 } else {
603 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530604 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000605 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
606 loUniPort = uniPort
607 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000609 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
610 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
611 flowInPort, dh.deviceID)
612 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000613 }
614 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000616 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000617 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000619 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000620 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000622 log.Fields{"device-id": dh.deviceID, "error": err})
623 retError = err
624 continue
625 //return err
626 } else { // if last setting succeeds, overwrite possibly previously set error
627 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000628 }
629 }
630 }
631 }
mpagenko01e726e2020-10-23 09:45:29 +0000632 if apOfFlowChanges.ToAdd != nil {
633 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
634 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000635 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000636 "device-id": dh.deviceID})
637 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
638 continue
639 }
640 flowInPort := flow.GetInPort(flowItem)
641 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 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 +0000643 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
644 continue
645 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
646 } else if flowInPort == dh.ponPortNumber {
647 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000649 "device-id": dh.deviceID, "inPort": flowInPort})
650 continue
651 } else {
652 // this is the relevant upstream flow
653 var loUniPort *onuUniPort
654 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
655 loUniPort = uniPort
656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000658 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
659 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
660 flowInPort, dh.deviceID)
661 continue
662 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
663 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000664 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
665 // if not, we just throw some error here to have an indication about that, if we really need to support that
666 // then we would need to create some means to activate the internal stored flows
667 // after the device gets active automatically (and still with its dependency to the TechProfile)
668 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
669 // also abort for the other still possible flows here
670 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000672 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000673 return fmt.Errorf("improper device state on device %s", dh.deviceID)
674 }
675
mpagenko01e726e2020-10-23 09:45:29 +0000676 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000678 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
679 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000681 //try next flow after processing error
682 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000684 log.Fields{"device-id": dh.deviceID, "error": err})
685 retError = err
686 continue
687 //return err
688 } else { // if last setting succeeds, overwrite possibly previously set error
689 retError = nil
690 }
691 }
692 }
693 }
694 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000695}
696
Himani Chawla6d2ae152020-09-02 13:11:20 +0530697//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000698//following are the expected device states after this activity:
699//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
700// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
702 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000703
mpagenko900ee4b2020-10-12 11:56:34 +0000704 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000705 //note that disableDevice sequences in some 'ONU active' state may yield also
706 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000707 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000708 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000709 //disable-device shall be just a UNi/ONU-G related admin state setting
710 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000711
mpagenkofc4f56e2020-11-04 17:17:49 +0000712 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000713 // disable UNI ports/ONU
714 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
715 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000717 } else { //LockStateFSM already init
718 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000720 }
721 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000723 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000725 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
726 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000728 }
mpagenko01e726e2020-10-23 09:45:29 +0000729 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000730
731 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000733 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300734 }
735}
736
Himani Chawla6d2ae152020-09-02 13:11:20 +0530737//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
739 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000740
mpagenkofc4f56e2020-11-04 17:17:49 +0000741 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
742 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
743 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
744 // for real ONU's that should have nearly no influence
745 // Note that for real ONU's there is anyway a problematic situation with following sequence:
746 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
747 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
748 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
749 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
750
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000751 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000752 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000753 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000755 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000756 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000757 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000758 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300759}
760
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
762 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000763
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000765 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000767 return
768 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000770 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000772 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000774 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000775 dh.reconciling = false
776 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000777 }
Himani Chawla4d908332020-08-31 12:30:20 +0530778 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000779 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
780 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
781 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
782 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000784}
785
dbainbri4d3a0dc2020-12-02 00:33:42 +0000786func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
787 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000788
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 return
793 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 dh.pOnuTP.lockTpProcMutex()
795 defer dh.pOnuTP.unlockTpProcMutex()
796
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000797 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000799 log.Fields{"device-id": dh.deviceID})
800 dh.reconciling = false
801 return
802 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000804 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
805 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000807 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
808 dh.reconciling = false
809 return
810 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800811 for tpID := range uniData.PersTpPathMap {
812 // deadline context to ensure completion of background routines waited for
813 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
814 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000816
Girish Gowdra041dcb32020-11-16 16:54:30 -0800817 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
818 var wg sync.WaitGroup
819 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
821 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800822 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800824 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000826 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000828 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
829 dh.reconciling = false
830 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 }
832}
833
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
835 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000840 return
841 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000842 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000844 log.Fields{"device-id": dh.deviceID})
845 dh.reconciling = false
846 return
847 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000849 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
850 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000852 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
853 dh.reconciling = false
854 return
855 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 var uniPort *onuUniPort
857 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 return
862 }
863 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000865 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000868 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
869 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000874 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000875 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 }
878 }
879 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000880 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
883 dh.reconciling = false
884 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 }
886}
887
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
889 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 +0000890
891 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000892 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000893}
894
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
896 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000897
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000900 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000902 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000903 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000904 pDevEntry.lockOnuKVStoreMutex()
905 defer pDevEntry.unlockOnuKVStoreMutex()
906
907 // deadline context to ensure completion of background routines waited for
908 //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 +0530909 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000911
912 pDevEntry.resetKvProcessingErrorIndication()
913
914 var wg sync.WaitGroup
915 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
917 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000918
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000919 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000920 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921}
922
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
924 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300925 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300928 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530930 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000931 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530932 return err
933 }
mpagenko01e726e2020-10-23 09:45:29 +0000934
935 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000936 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000937
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000939 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300941 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000942 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300944 return err
945 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300947 return err
948 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000949 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000950 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
951 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
952 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
953 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300954 return nil
955}
956
mpagenkoc8bba412021-01-15 15:38:44 +0000957//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
958func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
959 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
960 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
961 return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
962}
963
Himani Chawla6d2ae152020-09-02 13:11:20 +0530964// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000965// #####################################################################################
966
967// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530968// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000969
dbainbri4d3a0dc2020-12-02 00:33:42 +0000970func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
971 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 +0000972}
973
974// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000976
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000978 var err error
979
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000980 // populate what we know. rest comes later after mib sync
981 dh.device.Root = false
982 dh.device.Vendor = "OpenONU"
983 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000984 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000985 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000986
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000987 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000988
989 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000990 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
991 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530992 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000993 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000995 log.Fields{"device-id": dh.deviceID})
996 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997
Himani Chawla4d908332020-08-31 12:30:20 +0530998 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000999 dh.ponPortNumber = dh.device.ParentPortNo
1000
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001001 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1002 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1003 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001004 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001005 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301006 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001007
1008 /*
1009 self._pon = PonPort.create(self, self._pon_port_number)
1010 self._pon.add_peer(self.parent_id, self._pon_port_number)
1011 self.logger.debug('adding-pon-port-to-agent',
1012 type=self._pon.get_port().type,
1013 admin_state=self._pon.get_port().admin_state,
1014 oper_status=self._pon.get_port().oper_status,
1015 )
1016 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001017 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001018 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001019 var ponPortNo uint32 = 1
1020 if dh.ponPortNumber != 0 {
1021 ponPortNo = dh.ponPortNumber
1022 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001023
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001024 pPonPort := &voltha.Port{
1025 PortNo: ponPortNo,
1026 Label: fmt.Sprintf("pon-%d", ponPortNo),
1027 Type: voltha.Port_PON_ONU,
1028 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301029 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001030 PortNo: ponPortNo}}, // Peer port is parent's port number
1031 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001032 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1033 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001034 e.Cancel(err)
1035 return
1036 }
1037 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001038 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001039 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001040 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001041}
1042
1043// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001045
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001047 var err error
1048 /*
1049 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1050 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1051 return nil
1052 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001053 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1054 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001055 e.Cancel(err)
1056 return
1057 }
1058
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001059 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001060 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001061 // reconcilement will be continued after mib download is done
1062 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001063
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001064 /*
1065 ############################################################################
1066 # Setup Alarm handler
1067 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1068 device.serial_number)
1069 ############################################################################
1070 # Setup PM configuration for this device
1071 # Pass in ONU specific options
1072 kwargs = {
1073 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1074 'heartbeat': self.heartbeat,
1075 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1076 }
1077 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1078 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1079 self.logical_device_id, device.serial_number,
1080 grouped=True, freq_override=False, **kwargs)
1081 pm_config = self._pm_metrics.make_proto()
1082 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1083 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1084 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1085
1086 # Note, ONU ID and UNI intf set in add_uni_port method
1087 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1088 ani_ports=[self._pon])
1089
1090 # Code to Run OMCI Test Action
1091 kwargs_omci_test_action = {
1092 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1093 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1094 }
1095 serial_number = device.serial_number
1096 self._test_request = OmciTestRequest(self.core_proxy,
1097 self.omci_agent, self.device_id,
1098 AniG, serial_number,
1099 self.logical_device_id,
1100 exclusive=False,
1101 **kwargs_omci_test_action)
1102
1103 self.enabled = True
1104 else:
1105 self.logger.info('onu-already-activated')
1106 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001107
dbainbri4d3a0dc2020-12-02 00:33:42 +00001108 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001109}
1110
1111// doStateConnected get the device info and update to voltha core
1112// for comparison of the original method (not that easy to uncomment): compare here:
1113// voltha-openolt-adapter/adaptercore/device_handler.go
1114// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116
dbainbri4d3a0dc2020-12-02 00:33:42 +00001117 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301118 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121}
1122
1123// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301127 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001128 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130
1131 /*
1132 // Synchronous call to update device state - this method is run in its own go routine
1133 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1134 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001135 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 +00001136 return err
1137 }
1138 return nil
1139 */
1140}
1141
1142// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001143func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146 var err error
1147
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001148 device := dh.device
1149 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001150 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001152 e.Cancel(err)
1153 return
1154 }
1155
1156 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001158 /*
1159 // Update the all ports state on that device to disable
1160 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001161 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001162 return er
1163 }
1164
1165 //Update the device oper state and connection status
1166 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1167 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1168 dh.device = cloned
1169
1170 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001171 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001172 return er
1173 }
1174
1175 //get the child device for the parent device
1176 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1177 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001178 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001179 return err
1180 }
1181 for _, onuDevice := range onuDevices.Items {
1182
1183 // Update onu state as down in onu adapter
1184 onuInd := oop.OnuIndication{}
1185 onuInd.OperState = "down"
1186 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1187 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1188 if er != nil {
1189 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001190 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001191 //Do not return here and continue to process other ONUs
1192 }
1193 }
1194 // * Discovered ONUs entries need to be cleared , since after OLT
1195 // is up, it starts sending discovery indications again* /
1196 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001197 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001198 return nil
1199 */
Himani Chawla4d908332020-08-31 12:30:20 +05301200 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001201 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203}
1204
Himani Chawla6d2ae152020-09-02 13:11:20 +05301205// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206// #################################################################################
1207
1208// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301209// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001210
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001211//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001212func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001213 dh.lockDevice.RLock()
1214 pOnuDeviceEntry := dh.pOnuOmciDevice
1215 if aWait && pOnuDeviceEntry == nil {
1216 //keep the read sema short to allow for subsequent write
1217 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001218 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001219 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1220 // so it might be needed to wait here for that event with some timeout
1221 select {
1222 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001224 return nil
1225 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001227 // if written now, we can return the written value without sema
1228 return dh.pOnuOmciDevice
1229 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001230 }
mpagenko3af1f032020-06-10 08:53:41 +00001231 dh.lockDevice.RUnlock()
1232 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001233}
1234
Himani Chawla6d2ae152020-09-02 13:11:20 +05301235//setOnuDeviceEntry sets the ONU device entry within the handler
1236func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001237 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001238 dh.lockDevice.Lock()
1239 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001240 dh.pOnuOmciDevice = apDeviceEntry
1241 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001242 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001243}
1244
Himani Chawla6d2ae152020-09-02 13:11:20 +05301245//addOnuDeviceEntry creates a new ONU device or returns the existing
1246func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001247 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001248
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001250 if deviceEntry == nil {
1251 /* costum_me_map in python code seems always to be None,
1252 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1253 /* also no 'clock' argument - usage open ...*/
1254 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001255 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001256 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001257 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001258 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001259 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001260 // fire deviceEntry ready event to spread to possibly waiting processing
1261 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001263 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001265 }
1266 // might be updated with some error handling !!!
1267 return nil
1268}
1269
dbainbri4d3a0dc2020-12-02 00:33:42 +00001270func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1271 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001272 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1273
1274 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001275
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001277 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001279 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1280 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001281 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282 if err := dh.storePersistentData(ctx); err != nil {
1283 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001284 log.Fields{"device-id": dh.deviceID, "err": err})
1285 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001287 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001288 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001289 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1290 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001292 }
1293 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001295 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001296
1297 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298 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 +00001299 log.Fields{"device-id": dh.deviceID})
1300 dh.reconciling = false
1301 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001302 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001303 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1304 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1305 // 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 +00001306 // 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 +00001307 // so let's just try to keep it simple ...
1308 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001309 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001310 if err != nil || device == nil {
1311 //TODO: needs to handle error scenarios
1312 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1313 return errors.New("Voltha Device not found")
1314 }
1315 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001316
dbainbri4d3a0dc2020-12-02 00:33:42 +00001317 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001318 return err
mpagenko3af1f032020-06-10 08:53:41 +00001319 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001320
dbainbri4d3a0dc2020-12-02 00:33:42 +00001321 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001322
1323 /* this might be a good time for Omci Verify message? */
1324 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001325 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001326 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001327 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001328 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329
1330 /* give the handler some time here to wait for the OMCi verification result
1331 after Timeout start and try MibUpload FSM anyway
1332 (to prevent stopping on just not supported OMCI verification from ONU) */
1333 select {
1334 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001335 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001336 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001337 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001338 }
1339
1340 /* In py code it looks earlier (on activate ..)
1341 # Code to Run OMCI Test Action
1342 kwargs_omci_test_action = {
1343 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1344 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1345 }
1346 serial_number = device.serial_number
1347 self._test_request = OmciTestRequest(self.core_proxy,
1348 self.omci_agent, self.device_id,
1349 AniG, serial_number,
1350 self.logical_device_id,
1351 exclusive=False,
1352 **kwargs_omci_test_action)
1353 ...
1354 # Start test requests after a brief pause
1355 if not self._test_request_started:
1356 self._test_request_started = True
1357 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1358 reactor.callLater(tststart, self._test_request.start_collector)
1359
1360 */
1361 /* which is then: in omci_test_request.py : */
1362 /*
1363 def start_collector(self, callback=None):
1364 """
1365 Start the collection loop for an adapter if the frequency > 0
1366
1367 :param callback: (callable) Function to call to collect PM data
1368 """
1369 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1370 if callback is None:
1371 callback = self.perform_test_omci
1372
1373 if self.lc is None:
1374 self.lc = LoopingCall(callback)
1375
1376 if self.default_freq > 0:
1377 self.lc.start(interval=self.default_freq / 10)
1378
1379 def perform_test_omci(self):
1380 """
1381 Perform the initial test request
1382 """
1383 ani_g_entities = self._device.configuration.ani_g_entities
1384 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1385 is not None else None
1386 self._entity_id = ani_g_entities_ids[0]
1387 self.logger.info('perform-test', entity_class=self._entity_class,
1388 entity_id=self._entity_id)
1389 try:
1390 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1391 result = yield self._device.omci_cc.send(frame)
1392 if not result.fields['omci_message'].fields['success_code']:
1393 self.logger.info('Self-Test Submitted Successfully',
1394 code=result.fields[
1395 'omci_message'].fields['success_code'])
1396 else:
1397 raise TestFailure('Test Failure: {}'.format(
1398 result.fields['omci_message'].fields['success_code']))
1399 except TimeoutError as e:
1400 self.deferred.errback(failure.Failure(e))
1401
1402 except Exception as e:
1403 self.logger.exception('perform-test-Error', e=e,
1404 class_id=self._entity_class,
1405 entity_id=self._entity_id)
1406 self.deferred.errback(failure.Failure(e))
1407
1408 */
1409
1410 // PM related heartbeat??? !!!TODO....
1411 //self._heartbeat.enabled = True
1412
mpagenko1cc3cb42020-07-27 15:24:38 +00001413 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1414 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1415 * 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 +05301416 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001417 */
1418 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001419 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001420 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001421 if pMibUlFsm.Is(ulStDisabled) {
1422 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 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 +00001424 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301425 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301427 //Determine ONU status and start/re-start MIB Synchronization tasks
1428 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001429 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301430 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 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 +00001432 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001433 }
Himani Chawla4d908332020-08-31 12:30:20 +05301434 } else {
1435 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 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 +00001437 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301438 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001441 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001443 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001444 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001445 }
1446 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001448 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001449 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001450
1451 // Start PM collector routine
1452 go dh.startCollector(ctx)
1453
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454 return nil
1455}
1456
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001458 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001459 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001460 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001461 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001462
mpagenko900ee4b2020-10-12 11:56:34 +00001463 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1464 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1465 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001466 if err := dh.resetFsms(ctx); err != nil {
1467 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001468 log.Fields{"device-id": dh.deviceID, "error": err})
1469 // abort: system behavior is just unstable ...
1470 return err
1471 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001472 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001473 _ = 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 +00001474
1475 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1476 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1477 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001478 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001479 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001480 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001481 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001482 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001484
1485 //TODO!!! remove existing traffic profiles
1486 /* from py code, if TP's exist, remove them - not yet implemented
1487 self._tp = dict()
1488 # Let TP download happen again
1489 for uni_id in self._tp_service_specific_task:
1490 self._tp_service_specific_task[uni_id].clear()
1491 for uni_id in self._tech_profile_download_done:
1492 self._tech_profile_download_done[uni_id].clear()
1493 */
1494
dbainbri4d3a0dc2020-12-02 00:33:42 +00001495 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001496
mpagenkofc4f56e2020-11-04 17:17:49 +00001497 dh.ReadyForSpecificOmciConfig = false
1498
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001500 // abort: system behavior is just unstable ...
1501 return err
1502 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001504 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001506 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001507 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001509 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001510 // abort: system behavior is just unstable ...
1511 return err
1512 }
1513 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001515 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001516 return nil
1517}
1518
dbainbri4d3a0dc2020-12-02 00:33:42 +00001519func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001520 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1521 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1522 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1523 // and using the stop/reset event should never harm
1524
dbainbri4d3a0dc2020-12-02 00:33:42 +00001525 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001526 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001528 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1529 }
mpagenko900ee4b2020-10-12 11:56:34 +00001530 //the MibSync FSM might be active all the ONU-active time,
1531 // hence it must be stopped unconditionally
1532 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1533 if pMibUlFsm != nil {
1534 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1535 }
1536 //MibDownload may run
1537 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1538 if pMibDlFsm != nil {
1539 _ = pMibDlFsm.Event(dlEvReset)
1540 }
1541 //port lock/unlock FSM's may be active
1542 if dh.pUnlockStateFsm != nil {
1543 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1544 }
1545 if dh.pLockStateFsm != nil {
1546 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1547 }
1548 //techProfile related PonAniConfigFsm FSM may be active
1549 if dh.pOnuTP != nil {
1550 // should always be the case here
1551 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1552 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001553 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1554 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1555 }
mpagenko900ee4b2020-10-12 11:56:34 +00001556 }
1557 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001558 // reset the possibly existing VlanConfigFsm
1559 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1560 //VlanFilterFsm exists and was already started
1561 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1562 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001563 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001564 // no need to remove specific data
1565 pVlanFilterFsm.RequestClearPersistency(false)
1566 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001567 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1568 }
1569 }
1570 }
1571 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001572 // Stop collector routine for PM Counters
1573 dh.stopCollector <- true
1574
mpagenko900ee4b2020-10-12 11:56:34 +00001575 return nil
1576}
1577
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1579 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 +05301580
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1582 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001583 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001585 return
1586 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001587 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001588 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1589 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1590 for _, mgmtEntityID := range pptpInstKeys {
1591 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1592 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001593 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301594 i++
1595 }
1596 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301598 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001599 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1600 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301601 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001602 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301603 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301605 i++
1606 }
1607 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301609 }
1610 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301612 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001613 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1614 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1615 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1616 * disable/enable toggling here to allow traffic
1617 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1618 * like the py comment says:
1619 * # start by locking all the unis till mib sync and initial mib is downloaded
1620 * # this way we can capture the port down/up events when we are ready
1621 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301622
mpagenkoa40e99a2020-11-17 13:50:39 +00001623 // Init Uni Ports to Admin locked state
1624 // *** should generate UniLockStateDone event *****
1625 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001627 } else { //LockStateFSM already init
1628 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001630 }
1631}
1632
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1634 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301635 /* Mib download procedure -
1636 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1637 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001639 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001641 return
1642 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301643 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1644 if pMibDlFsm != nil {
1645 if pMibDlFsm.Is(dlStDisabled) {
1646 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 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 +05301648 // maybe try a FSM reset and then again ... - TODO!!!
1649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301651 // maybe use more specific states here for the specific download steps ...
1652 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301654 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301656 //Begin MIB data download (running autonomously)
1657 }
1658 }
1659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001661 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301662 // maybe try a FSM reset and then again ... - TODO!!!
1663 }
1664 /***** Mib download started */
1665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301667 }
1668}
1669
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1671 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301672 //initiate DevStateUpdate
1673 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001675 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301677 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1678 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301680 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301682 }
1683 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001685 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001687 return
1688 }
1689 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 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 +00001691 log.Fields{"device-id": dh.deviceID})
1692 dh.reconciling = false
1693 return
1694 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301696 log.Fields{"device-id": dh.deviceID})
1697 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001699 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301700 // *** should generate UniUnlockStateDone event *****
1701 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301703 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301704 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301706 }
1707}
1708
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1710 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301711
1712 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301714 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1716 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001717 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001719 return
1720 }
1721 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 if err := dh.storePersistentData(ctx); err != nil {
1723 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 log.Fields{"device-id": dh.deviceID, "err": err})
1725 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301726 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 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 +05301728 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001730 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301731 }
1732}
1733
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1735 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001736 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001738 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1739 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001740 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001741 }
1742
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001744 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001746
1747 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001749
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001751 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001753 return
1754 }
1755 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 if err := dh.storePersistentData(ctx); err != nil {
1757 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001758 log.Fields{"device-id": dh.deviceID, "err": err})
1759 }
mpagenko900ee4b2020-10-12 11:56:34 +00001760}
1761
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1763 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001764 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001766 voltha.OperStatus_ACTIVE); err != nil {
1767 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001769 }
1770
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001772 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001773 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001775
1776 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001778
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001780 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001782 return
1783 }
1784 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 if err := dh.storePersistentData(ctx); err != nil {
1786 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001787 log.Fields{"device-id": dh.deviceID, "err": err})
1788 }
mpagenko900ee4b2020-10-12 11:56:34 +00001789}
1790
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001792 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001794 // attention: the device reason update is done based on ONU-UNI-Port related activity
1795 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001796 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001797 // 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 +00001798 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301799 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001800 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001802 }
1803 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001805 // attention: the device reason update is done based on ONU-UNI-Port related activity
1806 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001807 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001808 // 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 +00001809 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001810 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001811 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301812}
1813
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1815 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001816 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301817 // attention: the device reason update is done based on ONU-UNI-Port related activity
1818 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301819
mpagenkofc4f56e2020-11-04 17:17:49 +00001820 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001821 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001822 // which may be the case from some previous actvity on another UNI Port of the ONU
1823 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001825 // request MDS-value for test and logging purposes
1826 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001827 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001829 }
1830 }
1831 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001832 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001833 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001835 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301836 }
1837}
1838
Himani Chawla6d2ae152020-09-02 13:11:20 +05301839//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301841 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001842 case MibDatabaseSync:
1843 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001845 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001846 case UniLockStateDone:
1847 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001849 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001850 case MibDownloadDone:
1851 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001852 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001853 }
1854 case UniUnlockStateDone:
1855 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001857 }
mpagenko900ee4b2020-10-12 11:56:34 +00001858 case UniEnableStateDone:
1859 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001861 }
1862 case UniDisableStateDone:
1863 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001865 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001866 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001867 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001869 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001870 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001871 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001873 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001874 default:
1875 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001877 }
1878 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001879}
1880
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001882 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301884 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001885 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001887 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301888 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001890 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001892 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001893 //store UniPort with the System-PortNumber key
1894 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001895 if !dh.reconciling {
1896 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1898 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001899 } //error logging already within UniPort method
1900 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001901 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001902 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001903 }
1904 }
1905}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001906
mpagenko3af1f032020-06-10 08:53:41 +00001907// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001909 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301910 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001911 // with following remark:
1912 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1913 // # load on the core
1914
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001915 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001916
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001917 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001918 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301919 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301921 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001922 if !dh.reconciling {
1923 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 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 +00001925 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001926 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001928 }
mpagenko3af1f032020-06-10 08:53:41 +00001929 }
1930 }
1931}
1932
1933// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001935 // compare enableUniPortStateUpdate() above
1936 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1937 for uniNo, uniPort := range dh.uniEntityMap {
1938 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301939 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301941 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001942 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 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 +00001944 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001945 }
1946}
1947
1948// ONU_Active/Inactive announcement on system KAFKA bus
1949// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001951 var de voltha.DeviceEvent
1952 eventContext := make(map[string]string)
1953 //Populating event context
1954 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001956 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301958 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001959 }
1960 oltSerialNumber := parentDevice.SerialNumber
1961
1962 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1963 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1964 eventContext["serial-number"] = dh.device.SerialNumber
1965 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301966 eventContext["device_id"] = aDeviceID
1967 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001969 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001970
1971 /* Populating device event body */
1972 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301973 de.ResourceId = aDeviceID
1974 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001975 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1976 de.Description = fmt.Sprintf("%s Event - %s - %s",
1977 cEventObjectType, cOnuActivatedEvent, "Raised")
1978 } else {
1979 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1980 de.Description = fmt.Sprintf("%s Event - %s - %s",
1981 cEventObjectType, cOnuActivatedEvent, "Cleared")
1982 }
1983 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1985 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301986 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001987 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301989 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001990}
1991
Himani Chawla4d908332020-08-31 12:30:20 +05301992// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001994 chLSFsm := make(chan Message, 2048)
1995 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301996 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001998 sFsmName = "LockStateFSM"
1999 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002001 sFsmName = "UnLockStateFSM"
2002 }
mpagenko3af1f032020-06-10 08:53:41 +00002003
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002005 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002006 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002007 return
2008 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002010 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002011 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302012 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002013 dh.pLockStateFsm = pLSFsm
2014 } else {
2015 dh.pUnlockStateFsm = pLSFsm
2016 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002017 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002018 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002020 }
2021}
2022
2023// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002025 /* Uni Port lock/unlock procedure -
2026 ***** should run via 'adminDone' state and generate the argument requested event *****
2027 */
2028 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302029 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002030 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2031 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2032 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002033 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302034 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002035 }
2036 } else {
2037 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2038 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2039 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002040 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302041 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002042 }
2043 }
2044 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002045 if pLSStatemachine.Is(uniStDisabled) {
2046 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002048 // maybe try a FSM reset and then again ... - TODO!!!
2049 } else {
2050 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002052 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002053 }
2054 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002056 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002057 // maybe try a FSM reset and then again ... - TODO!!!
2058 }
2059 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002061 // maybe try a FSM reset and then again ... - TODO!!!
2062 }
2063}
2064
Himani Chawla6d2ae152020-09-02 13:11:20 +05302065//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002067 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002069 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002070 kvbackend := &db.Backend{
2071 Client: dh.pOpenOnuAc.kvClient,
2072 StoreType: dh.pOpenOnuAc.KVStoreType,
2073 /* address config update acc. to [VOL-2736] */
2074 Address: addr,
2075 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2076 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002077
mpagenkoaf801632020-07-03 10:00:42 +00002078 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002079}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002080func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302081 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002082
mpagenkodff5dda2020-08-28 11:52:01 +00002083 for _, field := range flow.GetOfbFields(apFlowItem) {
2084 switch field.Type {
2085 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2086 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002087 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002088 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2089 }
mpagenko01e726e2020-10-23 09:45:29 +00002090 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002091 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2092 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302093 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002094 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302095 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2096 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002097 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2098 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002099 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2100 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302101 return
mpagenkodff5dda2020-08-28 11:52:01 +00002102 }
2103 }
mpagenko01e726e2020-10-23 09:45:29 +00002104 */
mpagenkodff5dda2020-08-28 11:52:01 +00002105 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2106 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302107 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002108 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302109 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002110 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302111 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002112 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302114 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002115 }
2116 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2117 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302118 *loAddPcp = uint8(field.GetVlanPcp())
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 "PCP": loAddPcp})
2121 }
2122 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2123 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002125 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2126 }
2127 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2128 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002130 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2131 }
2132 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2133 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002135 "IPv4-DST": field.GetIpv4Dst()})
2136 }
2137 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2138 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002139 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002140 "IPv4-SRC": field.GetIpv4Src()})
2141 }
2142 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2143 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002145 "Metadata": field.GetTableMetadata()})
2146 }
2147 /*
2148 default:
2149 {
2150 //all other entires ignored
2151 }
2152 */
2153 }
2154 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302155}
mpagenkodff5dda2020-08-28 11:52:01 +00002156
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002158 for _, action := range flow.GetActions(apFlowItem) {
2159 switch action.Type {
2160 /* not used:
2161 case of.OfpActionType_OFPAT_OUTPUT:
2162 {
mpagenko01e726e2020-10-23 09:45:29 +00002163 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002164 "Output": action.GetOutput()})
2165 }
2166 */
2167 case of.OfpActionType_OFPAT_PUSH_VLAN:
2168 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002170 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2171 }
2172 case of.OfpActionType_OFPAT_SET_FIELD:
2173 {
2174 pActionSetField := action.GetSetField()
2175 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002177 "OxcmClass": pActionSetField.Field.OxmClass})
2178 }
2179 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302180 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302182 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002183 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302184 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302186 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002187 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002189 "Type": pActionSetField.Field.GetOfbField().Type})
2190 }
2191 }
2192 /*
2193 default:
2194 {
2195 //all other entires ignored
2196 }
2197 */
2198 }
2199 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302200}
2201
2202//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302204 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2205 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2206 var loAddPcp, loSetPcp uint8
2207 var loIPProto uint32
2208 /* the TechProfileId is part of the flow Metadata - compare also comment within
2209 * OLT-Adapter:openolt_flowmgr.go
2210 * Metadata 8 bytes:
2211 * Most Significant 2 Bytes = Inner VLAN
2212 * Next 2 Bytes = Tech Profile ID(TPID)
2213 * Least Significant 4 Bytes = Port ID
2214 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2215 * subscriber related flows.
2216 */
2217
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302219 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002220 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302221 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002222 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302223 }
mpagenko551a4d42020-12-08 18:09:20 +00002224 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002225 loCookie := apFlowItem.GetCookie()
2226 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002228 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302229
dbainbri4d3a0dc2020-12-02 00:33:42 +00002230 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002231 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302232 if loIPProto == 2 {
2233 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2234 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002235 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2236 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302237 return nil
2238 }
mpagenko01e726e2020-10-23 09:45:29 +00002239 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002241
2242 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002243 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002244 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2245 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2246 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2247 //TODO!!: Use DeviceId within the error response to rwCore
2248 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002249 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002250 }
2251 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002253 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2254 } else {
2255 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2256 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2257 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302258 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002259 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002261 }
mpagenko9a304ea2020-12-16 15:54:01 +00002262
2263 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2264 dh.lockVlanConfig.Lock()
2265 defer dh.lockVlanConfig.Unlock()
2266 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302267 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002269 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002270 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002271 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002272 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002273}
2274
2275//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002277 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2278 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2279 //no extra check is done on the rule parameters
2280 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2281 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2282 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2283 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002284 // - 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 +00002285 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002287
2288 /* TT related temporary workaround - should not be needed anymore
2289 for _, field := range flow.GetOfbFields(apFlowItem) {
2290 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2291 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002292 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002293 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2294 if loIPProto == 2 {
2295 // 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 +00002296 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002297 log.Fields{"device-id": dh.deviceID})
2298 return nil
2299 }
2300 }
2301 } //for all OfbFields
2302 */
2303
mpagenko9a304ea2020-12-16 15:54:01 +00002304 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2305 dh.lockVlanConfig.Lock()
2306 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002307 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002309 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002311 log.Fields{"device-id": dh.deviceID})
2312 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002313 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002314 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002315
mpagenko01e726e2020-10-23 09:45:29 +00002316 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002317}
2318
Himani Chawla26e555c2020-08-31 12:30:20 +05302319// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002320// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002321func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002322 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002323 chVlanFilterFsm := make(chan Message, 2048)
2324
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002326 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302328 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002329 }
2330
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002332 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2333 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002334 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302335 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002336 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2337 if pVlanFilterStatemachine != nil {
2338 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2339 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302341 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002342 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302343 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2346 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002347 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002349 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302350 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002351 }
2352 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002354 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302355 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002356 }
2357 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002359 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302360 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002361 }
2362 return nil
2363}
2364
mpagenkofc4f56e2020-11-04 17:17:49 +00002365//VerifyVlanConfigRequest checks on existence of a given uniPort
2366// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002367func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002368 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2369 var pCurrentUniPort *onuUniPort
2370 for _, uniPort := range dh.uniEntityMap {
2371 // only if this port is validated for operState transfer
2372 if uniPort.uniID == uint8(aUniID) {
2373 pCurrentUniPort = uniPort
2374 break //found - end search loop
2375 }
2376 }
2377 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002379 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2380 return
2381 }
mpagenko551a4d42020-12-08 18:09:20 +00002382 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002383}
2384
mpagenkodff5dda2020-08-28 11:52:01 +00002385//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002386func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002387 //TODO!! verify and start pending flow configuration
2388 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2389 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302390 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002391 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2392 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2393 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002394 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2395 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2396 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2397 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2398 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2399 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2400 } else {
2401 /***** UniVlanConfigFsm continued */
2402 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2403 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2404 "UniPort": apUniPort.portNo})
2405 }
2406 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2407 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2408 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2409 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2410 } else {
2411 /***** UniVlanConfigFsm continued */
2412 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2413 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2414 "UniPort": apUniPort.portNo})
2415 }
mpagenkodff5dda2020-08-28 11:52:01 +00002416 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002417 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2418 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002419 "UniPort": apUniPort.portNo})
2420 }
2421 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002422 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2423 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2424 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002425 }
2426 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002427 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002428 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002429 }
mpagenkodff5dda2020-08-28 11:52:01 +00002430 } // else: nothing to do
2431}
2432
2433//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2434// 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 +00002435func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2436 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002437 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2438 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302439 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002440}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002441
2442//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2443//available for potential reconcilement
2444
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002446
2447 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002448 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002449 return nil
2450 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002452
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002454 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002456 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2457 }
2458 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2459
2460 pDevEntry.lockOnuKVStoreMutex()
2461 defer pDevEntry.unlockOnuKVStoreMutex()
2462
2463 // deadline context to ensure completion of background routines waited for
2464 //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 +05302465 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002466 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2467
2468 pDevEntry.resetKvProcessingErrorIndication()
2469 var wg sync.WaitGroup
2470 wg.Add(1) // for the 1 go routine to finish
2471
dbainbri4d3a0dc2020-12-02 00:33:42 +00002472 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2473 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002474
2475 return pDevEntry.getKvProcessingErrorIndication()
2476}
2477
dbainbri4d3a0dc2020-12-02 00:33:42 +00002478func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002479 defer cancel() //ensure termination of context (may be pro forma)
2480 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002482 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002483}
2484
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002486
2487 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002488 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002489 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002490 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2491 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002492 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002493 return err
2494 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002496 return nil
2497 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002498 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002499 return nil
2500}
2501
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2503 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002504 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002505 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002506 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2507 }
2508 pDevEntry.lockOnuKVStoreMutex()
2509 defer pDevEntry.unlockOnuKVStoreMutex()
2510
2511 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2512 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2513
2514 pDevEntry.resetKvProcessingErrorIndication()
2515 var wg sync.WaitGroup
2516 wg.Add(1) // for the 1 go routine to finish
2517
2518 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002520
2521 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002522 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002523 return err
2524 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002525 return nil
2526}
2527
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002528func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2529 var errStr string = ""
2530 for _, err := range errS {
2531 if err != nil {
2532 errStr = errStr + err.Error() + " "
2533 }
2534 }
2535 if errStr != "" {
2536 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2537 }
2538 return nil
2539}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002540
2541// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2542func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2543 dh.lockDevice.RLock()
2544 defer dh.lockDevice.RUnlock()
2545 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2546 return uniPort.entityID, nil
2547 }
2548 return 0, errors.New("error-fetching-uni-port")
2549}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002550
2551// updatePmConfig updates the pm metrics config.
2552func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
2553 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
2554
2555 // TODO: Currently support only updating the PM Sampling Frequency
2556 if pmConfigs.DefaultFreq != dh.pmMetrics.ToPmConfigs().DefaultFreq {
2557 dh.pmMetrics.UpdateFrequency(pmConfigs.DefaultFreq)
2558 logger.Debugw(ctx, "frequency-updated--new-frequency", log.Fields{"device-id": dh.deviceID, "frequency": dh.pmMetrics.ToPmConfigs().DefaultFreq})
2559 } else {
2560 logger.Debugw(ctx, "new-frequency-same-as-old--not-updating", log.Fields{"frequency": pmConfigs.DefaultFreq})
2561 }
2562}
2563
2564func (dh *deviceHandler) startCollector(ctx context.Context) {
2565 logger.Debugf(ctx, "startingCollector")
2566
2567 // Start routine to process OMCI GET Responses
2568 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
2569
2570 for {
2571 select {
2572 case <-dh.stopCollector:
2573 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2574 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2575 return
2576 case <-time.After(time.Duration(dh.pmMetrics.ToPmConfigs().DefaultFreq) * time.Second):
2577 go func() {
2578 logger.Debug(ctx, "startCollector before collecting optical metrics")
2579 metricInfo := dh.pOnuMetricsMgr.collectOpticalMetrics(ctx)
2580 dh.pOnuMetricsMgr.publishMetrics(ctx, metricInfo)
2581 }()
2582
2583 go func() {
2584 logger.Debug(ctx, "startCollector before collecting uni metrics")
2585 metricInfo := dh.pOnuMetricsMgr.collectUniStatusMetrics(ctx)
2586 dh.pOnuMetricsMgr.publishMetrics(ctx, metricInfo)
2587 }()
2588 }
2589 }
2590}