blob: 64e8f24892a9daff6753cab71b796bc59e40a7a3 [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
mpagenko057889c2021-01-21 16:51:58 +0000302func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(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
mpagenko057889c2021-01-21 16:51:58 +0000549 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
550 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000551 {
mpagenko057889c2021-01-21 16:51:58 +0000552 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000553 }
mpagenkoaf801632020-07-03 10:00:42 +0000554 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
555 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000556 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000557 }
558 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
559 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000560 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000561
mpagenkoaf801632020-07-03 10:00:42 +0000562 }
563 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
564 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000565 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000566 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000567 default:
568 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000570 "msgType": msg.Header.Type, "device-id": dh.deviceID})
571 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000572 }
573 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000574}
575
mpagenkodff5dda2020-08-28 11:52:01 +0000576//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000577func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
578 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000579 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000581
mpagenko01e726e2020-10-23 09:45:29 +0000582 var retError error = nil
583 //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 +0000584 if apOfFlowChanges.ToRemove != nil {
585 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000586 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000588 "device-id": dh.deviceID})
589 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000590 continue
591 }
592 flowInPort := flow.GetInPort(flowItem)
593 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000594 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 +0000595 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
596 continue
597 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000598 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000599 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000600 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000601 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000602 continue
603 } else {
604 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530605 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000606 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
607 loUniPort = uniPort
608 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000609 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000610 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
611 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
612 flowInPort, dh.deviceID)
613 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000614 }
615 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000617 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000618 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000620 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000621 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000623 log.Fields{"device-id": dh.deviceID, "error": err})
624 retError = err
625 continue
626 //return err
627 } else { // if last setting succeeds, overwrite possibly previously set error
628 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000629 }
630 }
631 }
632 }
mpagenko01e726e2020-10-23 09:45:29 +0000633 if apOfFlowChanges.ToAdd != nil {
634 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
635 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000637 "device-id": dh.deviceID})
638 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
639 continue
640 }
641 flowInPort := flow.GetInPort(flowItem)
642 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 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 +0000644 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
645 continue
646 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
647 } else if flowInPort == dh.ponPortNumber {
648 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000650 "device-id": dh.deviceID, "inPort": flowInPort})
651 continue
652 } else {
653 // this is the relevant upstream flow
654 var loUniPort *onuUniPort
655 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
656 loUniPort = uniPort
657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000659 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
660 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
661 flowInPort, dh.deviceID)
662 continue
663 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
664 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000665 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
666 // if not, we just throw some error here to have an indication about that, if we really need to support that
667 // then we would need to create some means to activate the internal stored flows
668 // after the device gets active automatically (and still with its dependency to the TechProfile)
669 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
670 // also abort for the other still possible flows here
671 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000673 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000674 return fmt.Errorf("improper device state on device %s", dh.deviceID)
675 }
676
mpagenko01e726e2020-10-23 09:45:29 +0000677 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000679 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
680 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000682 //try next flow after processing error
683 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000684 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000685 log.Fields{"device-id": dh.deviceID, "error": err})
686 retError = err
687 continue
688 //return err
689 } else { // if last setting succeeds, overwrite possibly previously set error
690 retError = nil
691 }
692 }
693 }
694 }
695 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000696}
697
Himani Chawla6d2ae152020-09-02 13:11:20 +0530698//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000699//following are the expected device states after this activity:
700//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
701// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
703 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000704
mpagenko900ee4b2020-10-12 11:56:34 +0000705 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000706 //note that disableDevice sequences in some 'ONU active' state may yield also
707 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000708 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000709 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000710 //disable-device shall be just a UNi/ONU-G related admin state setting
711 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000712
mpagenkofc4f56e2020-11-04 17:17:49 +0000713 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000714 // disable UNI ports/ONU
715 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
716 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000718 } else { //LockStateFSM already init
719 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000721 }
722 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000724 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000725 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000726 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
727 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000729 }
mpagenko01e726e2020-10-23 09:45:29 +0000730 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000731
732 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000734 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300735 }
736}
737
Himani Chawla6d2ae152020-09-02 13:11:20 +0530738//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000739func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
740 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000741
mpagenkofc4f56e2020-11-04 17:17:49 +0000742 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
743 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
744 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
745 // for real ONU's that should have nearly no influence
746 // Note that for real ONU's there is anyway a problematic situation with following sequence:
747 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
748 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
749 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
750 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
751
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000752 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000753 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000754 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000756 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000757 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000759 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300760}
761
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
763 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000764
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000766 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000767 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000768 return
769 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000771 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000773 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000775 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000776 dh.reconciling = false
777 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000778 }
Himani Chawla4d908332020-08-31 12:30:20 +0530779 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000780 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
781 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
782 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
783 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000785}
786
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
788 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000789
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000791 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000793 return
794 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000795 dh.pOnuTP.lockTpProcMutex()
796 defer dh.pOnuTP.unlockTpProcMutex()
797
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000798 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000800 log.Fields{"device-id": dh.deviceID})
801 dh.reconciling = false
802 return
803 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000804 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000805 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
806 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000808 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
809 dh.reconciling = false
810 return
811 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800812 for tpID := range uniData.PersTpPathMap {
813 // deadline context to ensure completion of background routines waited for
814 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
815 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000817
Girish Gowdra041dcb32020-11-16 16:54:30 -0800818 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
819 var wg sync.WaitGroup
820 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
822 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800823 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800825 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000827 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000828 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000829 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
830 dh.reconciling = false
831 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 }
833}
834
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
836 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000837
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000839 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000841 return
842 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000843 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000845 log.Fields{"device-id": dh.deviceID})
846 dh.reconciling = false
847 return
848 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000849 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000850 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
851 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000853 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
854 dh.reconciling = false
855 return
856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 var uniPort *onuUniPort
858 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000862 return
863 }
864 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000866 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000867 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000869 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
870 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000873 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000875 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000876 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878 }
879 }
880 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000881 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000882 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
884 dh.reconciling = false
885 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000886 }
887}
888
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
890 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 +0000891
892 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000893 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000894}
895
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
897 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000900 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000901 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000903 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000904 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905 pDevEntry.lockOnuKVStoreMutex()
906 defer pDevEntry.unlockOnuKVStoreMutex()
907
908 // deadline context to ensure completion of background routines waited for
909 //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 +0530910 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000912
913 pDevEntry.resetKvProcessingErrorIndication()
914
915 var wg sync.WaitGroup
916 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
918 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000919
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000920 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000921 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000922}
923
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
925 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300926 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000928 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300929 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530931 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000932 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530933 return err
934 }
mpagenko01e726e2020-10-23 09:45:29 +0000935
936 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000938
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000940 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000941 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300942 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000943 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300945 return err
946 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300948 return err
949 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000950 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000951 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
952 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
953 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
954 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300955 return nil
956}
957
mpagenkoc8bba412021-01-15 15:38:44 +0000958//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
959func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
960 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
961 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000962 //return success to comfort the core processing during integration
963 return nil
964 // TODO!!: also verify error response behavior
965 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000966}
967
Himani Chawla6d2ae152020-09-02 13:11:20 +0530968// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000969// #####################################################################################
970
971// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530972// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000973
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
975 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 +0000976}
977
978// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000979func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000980
dbainbri4d3a0dc2020-12-02 00:33:42 +0000981 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000982 var err error
983
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000984 // populate what we know. rest comes later after mib sync
985 dh.device.Root = false
986 dh.device.Vendor = "OpenONU"
987 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000988 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000989 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000990
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000991 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000992
993 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
995 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530996 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000997 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000998 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000999 log.Fields{"device-id": dh.deviceID})
1000 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001001
Himani Chawla4d908332020-08-31 12:30:20 +05301002 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001003 dh.ponPortNumber = dh.device.ParentPortNo
1004
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001005 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1006 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1007 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001009 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301010 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001011
1012 /*
1013 self._pon = PonPort.create(self, self._pon_port_number)
1014 self._pon.add_peer(self.parent_id, self._pon_port_number)
1015 self.logger.debug('adding-pon-port-to-agent',
1016 type=self._pon.get_port().type,
1017 admin_state=self._pon.get_port().admin_state,
1018 oper_status=self._pon.get_port().oper_status,
1019 )
1020 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001021 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001023 var ponPortNo uint32 = 1
1024 if dh.ponPortNumber != 0 {
1025 ponPortNo = dh.ponPortNumber
1026 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001027
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001028 pPonPort := &voltha.Port{
1029 PortNo: ponPortNo,
1030 Label: fmt.Sprintf("pon-%d", ponPortNo),
1031 Type: voltha.Port_PON_ONU,
1032 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301033 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001034 PortNo: ponPortNo}}, // Peer port is parent's port number
1035 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001036 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1037 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001038 e.Cancel(err)
1039 return
1040 }
1041 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001042 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001043 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001045}
1046
1047// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001048func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001049
dbainbri4d3a0dc2020-12-02 00:33:42 +00001050 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001051 var err error
1052 /*
1053 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1054 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1055 return nil
1056 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001057 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1058 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001059 e.Cancel(err)
1060 return
1061 }
1062
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001063 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001065 // reconcilement will be continued after mib download is done
1066 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001067
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001068 /*
1069 ############################################################################
1070 # Setup Alarm handler
1071 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1072 device.serial_number)
1073 ############################################################################
1074 # Setup PM configuration for this device
1075 # Pass in ONU specific options
1076 kwargs = {
1077 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1078 'heartbeat': self.heartbeat,
1079 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1080 }
1081 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1082 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1083 self.logical_device_id, device.serial_number,
1084 grouped=True, freq_override=False, **kwargs)
1085 pm_config = self._pm_metrics.make_proto()
1086 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1087 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1088 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1089
1090 # Note, ONU ID and UNI intf set in add_uni_port method
1091 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1092 ani_ports=[self._pon])
1093
1094 # Code to Run OMCI Test Action
1095 kwargs_omci_test_action = {
1096 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1097 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1098 }
1099 serial_number = device.serial_number
1100 self._test_request = OmciTestRequest(self.core_proxy,
1101 self.omci_agent, self.device_id,
1102 AniG, serial_number,
1103 self.logical_device_id,
1104 exclusive=False,
1105 **kwargs_omci_test_action)
1106
1107 self.enabled = True
1108 else:
1109 self.logger.info('onu-already-activated')
1110 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001111
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001113}
1114
1115// doStateConnected get the device info and update to voltha core
1116// for comparison of the original method (not that easy to uncomment): compare here:
1117// voltha-openolt-adapter/adaptercore/device_handler.go
1118// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001120
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301122 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001123 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125}
1126
1127// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001129
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301131 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001133 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001134
1135 /*
1136 // Synchronous call to update device state - this method is run in its own go routine
1137 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1138 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001139 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 +00001140 return err
1141 }
1142 return nil
1143 */
1144}
1145
1146// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001148
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001150 var err error
1151
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001152 device := dh.device
1153 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001154 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001156 e.Cancel(err)
1157 return
1158 }
1159
1160 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001162 /*
1163 // Update the all ports state on that device to disable
1164 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001165 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001166 return er
1167 }
1168
1169 //Update the device oper state and connection status
1170 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1171 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1172 dh.device = cloned
1173
1174 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001175 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176 return er
1177 }
1178
1179 //get the child device for the parent device
1180 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1181 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001182 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183 return err
1184 }
1185 for _, onuDevice := range onuDevices.Items {
1186
1187 // Update onu state as down in onu adapter
1188 onuInd := oop.OnuIndication{}
1189 onuInd.OperState = "down"
1190 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1191 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1192 if er != nil {
1193 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001194 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001195 //Do not return here and continue to process other ONUs
1196 }
1197 }
1198 // * Discovered ONUs entries need to be cleared , since after OLT
1199 // is up, it starts sending discovery indications again* /
1200 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001201 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001202 return nil
1203 */
Himani Chawla4d908332020-08-31 12:30:20 +05301204 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001205 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001207}
1208
Himani Chawla6d2ae152020-09-02 13:11:20 +05301209// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001210// #################################################################################
1211
1212// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301213// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001214
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001215//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001216func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001217 dh.lockDevice.RLock()
1218 pOnuDeviceEntry := dh.pOnuOmciDevice
1219 if aWait && pOnuDeviceEntry == nil {
1220 //keep the read sema short to allow for subsequent write
1221 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001223 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1224 // so it might be needed to wait here for that event with some timeout
1225 select {
1226 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001227 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001228 return nil
1229 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001231 // if written now, we can return the written value without sema
1232 return dh.pOnuOmciDevice
1233 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001234 }
mpagenko3af1f032020-06-10 08:53:41 +00001235 dh.lockDevice.RUnlock()
1236 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001237}
1238
Himani Chawla6d2ae152020-09-02 13:11:20 +05301239//setOnuDeviceEntry sets the ONU device entry within the handler
1240func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001241 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001242 dh.lockDevice.Lock()
1243 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001244 dh.pOnuOmciDevice = apDeviceEntry
1245 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001246 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001247}
1248
Himani Chawla6d2ae152020-09-02 13:11:20 +05301249//addOnuDeviceEntry creates a new ONU device or returns the existing
1250func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001252
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001254 if deviceEntry == nil {
1255 /* costum_me_map in python code seems always to be None,
1256 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1257 /* also no 'clock' argument - usage open ...*/
1258 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001259 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001260 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001261 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001262 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001263 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001264 // fire deviceEntry ready event to spread to possibly waiting processing
1265 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001269 }
1270 // might be updated with some error handling !!!
1271 return nil
1272}
1273
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1275 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001276 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1277
1278 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001279
dbainbri4d3a0dc2020-12-02 00:33:42 +00001280 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001281 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001283 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1284 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001285 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 if err := dh.storePersistentData(ctx); err != nil {
1287 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001288 log.Fields{"device-id": dh.deviceID, "err": err})
1289 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001290 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001291 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001293 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1294 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001296 }
1297 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001299 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001300
1301 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001302 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 +00001303 log.Fields{"device-id": dh.deviceID})
1304 dh.reconciling = false
1305 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001306 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001307 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1308 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1309 // 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 +00001310 // 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 +00001311 // so let's just try to keep it simple ...
1312 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001313 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001314 if err != nil || device == nil {
1315 //TODO: needs to handle error scenarios
1316 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1317 return errors.New("Voltha Device not found")
1318 }
1319 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001320
dbainbri4d3a0dc2020-12-02 00:33:42 +00001321 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001322 return err
mpagenko3af1f032020-06-10 08:53:41 +00001323 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001324
dbainbri4d3a0dc2020-12-02 00:33:42 +00001325 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001326
1327 /* this might be a good time for Omci Verify message? */
1328 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001329 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001330 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001331 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001332 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001333
1334 /* give the handler some time here to wait for the OMCi verification result
1335 after Timeout start and try MibUpload FSM anyway
1336 (to prevent stopping on just not supported OMCI verification from ONU) */
1337 select {
1338 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001339 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001340 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342 }
1343
1344 /* In py code it looks earlier (on activate ..)
1345 # Code to Run OMCI Test Action
1346 kwargs_omci_test_action = {
1347 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1348 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1349 }
1350 serial_number = device.serial_number
1351 self._test_request = OmciTestRequest(self.core_proxy,
1352 self.omci_agent, self.device_id,
1353 AniG, serial_number,
1354 self.logical_device_id,
1355 exclusive=False,
1356 **kwargs_omci_test_action)
1357 ...
1358 # Start test requests after a brief pause
1359 if not self._test_request_started:
1360 self._test_request_started = True
1361 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1362 reactor.callLater(tststart, self._test_request.start_collector)
1363
1364 */
1365 /* which is then: in omci_test_request.py : */
1366 /*
1367 def start_collector(self, callback=None):
1368 """
1369 Start the collection loop for an adapter if the frequency > 0
1370
1371 :param callback: (callable) Function to call to collect PM data
1372 """
1373 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1374 if callback is None:
1375 callback = self.perform_test_omci
1376
1377 if self.lc is None:
1378 self.lc = LoopingCall(callback)
1379
1380 if self.default_freq > 0:
1381 self.lc.start(interval=self.default_freq / 10)
1382
1383 def perform_test_omci(self):
1384 """
1385 Perform the initial test request
1386 """
1387 ani_g_entities = self._device.configuration.ani_g_entities
1388 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1389 is not None else None
1390 self._entity_id = ani_g_entities_ids[0]
1391 self.logger.info('perform-test', entity_class=self._entity_class,
1392 entity_id=self._entity_id)
1393 try:
1394 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1395 result = yield self._device.omci_cc.send(frame)
1396 if not result.fields['omci_message'].fields['success_code']:
1397 self.logger.info('Self-Test Submitted Successfully',
1398 code=result.fields[
1399 'omci_message'].fields['success_code'])
1400 else:
1401 raise TestFailure('Test Failure: {}'.format(
1402 result.fields['omci_message'].fields['success_code']))
1403 except TimeoutError as e:
1404 self.deferred.errback(failure.Failure(e))
1405
1406 except Exception as e:
1407 self.logger.exception('perform-test-Error', e=e,
1408 class_id=self._entity_class,
1409 entity_id=self._entity_id)
1410 self.deferred.errback(failure.Failure(e))
1411
1412 */
1413
1414 // PM related heartbeat??? !!!TODO....
1415 //self._heartbeat.enabled = True
1416
mpagenko1cc3cb42020-07-27 15:24:38 +00001417 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1418 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1419 * 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 +05301420 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001421 */
1422 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001423 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001424 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001425 if pMibUlFsm.Is(ulStDisabled) {
1426 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001427 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 +00001428 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301429 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301431 //Determine ONU status and start/re-start MIB Synchronization tasks
1432 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001433 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301434 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435 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 +00001436 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001437 }
Himani Chawla4d908332020-08-31 12:30:20 +05301438 } else {
1439 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001440 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 +00001441 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301442 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001444 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001445 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001447 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001448 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001449 }
1450 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001452 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001453 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001454
1455 // Start PM collector routine
1456 go dh.startCollector(ctx)
1457
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001458 return nil
1459}
1460
dbainbri4d3a0dc2020-12-02 00:33:42 +00001461func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001462 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001463 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001464 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001466
mpagenko900ee4b2020-10-12 11:56:34 +00001467 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1468 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1469 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001470 if err := dh.resetFsms(ctx); err != nil {
1471 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001472 log.Fields{"device-id": dh.deviceID, "error": err})
1473 // abort: system behavior is just unstable ...
1474 return err
1475 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001476 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477 _ = 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 +00001478
1479 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1480 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1481 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001483 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001485 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001486 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001488
1489 //TODO!!! remove existing traffic profiles
1490 /* from py code, if TP's exist, remove them - not yet implemented
1491 self._tp = dict()
1492 # Let TP download happen again
1493 for uni_id in self._tp_service_specific_task:
1494 self._tp_service_specific_task[uni_id].clear()
1495 for uni_id in self._tech_profile_download_done:
1496 self._tech_profile_download_done[uni_id].clear()
1497 */
1498
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001500
mpagenkofc4f56e2020-11-04 17:17:49 +00001501 dh.ReadyForSpecificOmciConfig = false
1502
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001504 // abort: system behavior is just unstable ...
1505 return err
1506 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001508 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001510 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001511 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001512 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001513 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001514 // abort: system behavior is just unstable ...
1515 return err
1516 }
1517 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001519 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001520 return nil
1521}
1522
dbainbri4d3a0dc2020-12-02 00:33:42 +00001523func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001524 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1525 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1526 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1527 // and using the stop/reset event should never harm
1528
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001530 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001532 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1533 }
mpagenko900ee4b2020-10-12 11:56:34 +00001534 //the MibSync FSM might be active all the ONU-active time,
1535 // hence it must be stopped unconditionally
1536 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1537 if pMibUlFsm != nil {
1538 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1539 }
1540 //MibDownload may run
1541 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1542 if pMibDlFsm != nil {
1543 _ = pMibDlFsm.Event(dlEvReset)
1544 }
1545 //port lock/unlock FSM's may be active
1546 if dh.pUnlockStateFsm != nil {
1547 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1548 }
1549 if dh.pLockStateFsm != nil {
1550 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1551 }
1552 //techProfile related PonAniConfigFsm FSM may be active
1553 if dh.pOnuTP != nil {
1554 // should always be the case here
1555 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1556 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001557 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1558 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1559 }
mpagenko900ee4b2020-10-12 11:56:34 +00001560 }
1561 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001562 // reset the possibly existing VlanConfigFsm
1563 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1564 //VlanFilterFsm exists and was already started
1565 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1566 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001567 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001568 // no need to remove specific data
1569 pVlanFilterFsm.RequestClearPersistency(false)
1570 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001571 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1572 }
1573 }
1574 }
1575 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001576 // Stop collector routine for PM Counters
1577 dh.stopCollector <- true
1578
mpagenko900ee4b2020-10-12 11:56:34 +00001579 return nil
1580}
1581
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1583 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 +05301584
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1586 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001587 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001589 return
1590 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001591 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001592 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1593 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1594 for _, mgmtEntityID := range pptpInstKeys {
1595 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1596 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301598 i++
1599 }
1600 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301602 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001603 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1604 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301605 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001606 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301607 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301609 i++
1610 }
1611 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301613 }
1614 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301616 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001617 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1618 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1619 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1620 * disable/enable toggling here to allow traffic
1621 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1622 * like the py comment says:
1623 * # start by locking all the unis till mib sync and initial mib is downloaded
1624 * # this way we can capture the port down/up events when we are ready
1625 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301626
mpagenkoa40e99a2020-11-17 13:50:39 +00001627 // Init Uni Ports to Admin locked state
1628 // *** should generate UniLockStateDone event *****
1629 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001631 } else { //LockStateFSM already init
1632 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001634 }
1635}
1636
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1638 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301639 /* Mib download procedure -
1640 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1641 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001643 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001645 return
1646 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301647 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1648 if pMibDlFsm != nil {
1649 if pMibDlFsm.Is(dlStDisabled) {
1650 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 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 +05301652 // maybe try a FSM reset and then again ... - TODO!!!
1653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301655 // maybe use more specific states here for the specific download steps ...
1656 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301660 //Begin MIB data download (running autonomously)
1661 }
1662 }
1663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001665 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301666 // maybe try a FSM reset and then again ... - TODO!!!
1667 }
1668 /***** Mib download started */
1669 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301671 }
1672}
1673
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1675 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 //initiate DevStateUpdate
1677 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001679 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301681 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1682 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301684 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301686 }
1687 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001689 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001691 return
1692 }
1693 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 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 +00001695 log.Fields{"device-id": dh.deviceID})
1696 dh.reconciling = false
1697 return
1698 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001699 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301700 log.Fields{"device-id": dh.deviceID})
1701 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001703 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301704 // *** should generate UniUnlockStateDone event *****
1705 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301707 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301708 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301710 }
1711}
1712
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1714 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301715
1716 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301718 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1720 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001721 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001723 return
1724 }
1725 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 if err := dh.storePersistentData(ctx); err != nil {
1727 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001728 log.Fields{"device-id": dh.deviceID, "err": err})
1729 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301730 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 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 +05301732 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001734 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301735 }
1736}
1737
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1739 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001740 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001742 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1743 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001745 }
1746
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001748 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001750
1751 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001753
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001755 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001757 return
1758 }
1759 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 if err := dh.storePersistentData(ctx); err != nil {
1761 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001762 log.Fields{"device-id": dh.deviceID, "err": err})
1763 }
mpagenko900ee4b2020-10-12 11:56:34 +00001764}
1765
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1767 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001768 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001770 voltha.OperStatus_ACTIVE); err != nil {
1771 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001773 }
1774
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001776 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001777 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001779
1780 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001782
dbainbri4d3a0dc2020-12-02 00:33:42 +00001783 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001784 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001786 return
1787 }
1788 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 if err := dh.storePersistentData(ctx); err != nil {
1790 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001791 log.Fields{"device-id": dh.deviceID, "err": err})
1792 }
mpagenko900ee4b2020-10-12 11:56:34 +00001793}
1794
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001796 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001798 // attention: the device reason update is done based on ONU-UNI-Port related activity
1799 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001800 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001801 // 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 +00001802 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301803 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001804 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001806 }
1807 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001809 // attention: the device reason update is done based on ONU-UNI-Port related activity
1810 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001811 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001812 // 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 +00001813 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001814 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001815 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301816}
1817
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1819 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001820 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301821 // attention: the device reason update is done based on ONU-UNI-Port related activity
1822 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301823
mpagenkofc4f56e2020-11-04 17:17:49 +00001824 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001825 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001826 // which may be the case from some previous actvity on another UNI Port of the ONU
1827 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001829 // request MDS-value for test and logging purposes
1830 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001831 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001833 }
1834 }
1835 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001836 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001837 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001838 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001839 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301840 }
1841}
1842
Himani Chawla6d2ae152020-09-02 13:11:20 +05301843//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301845 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001846 case MibDatabaseSync:
1847 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001849 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001850 case UniLockStateDone:
1851 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001852 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001853 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001854 case MibDownloadDone:
1855 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001857 }
1858 case UniUnlockStateDone:
1859 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001861 }
mpagenko900ee4b2020-10-12 11:56:34 +00001862 case UniEnableStateDone:
1863 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001865 }
1866 case UniDisableStateDone:
1867 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001869 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001870 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001871 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001873 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001874 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001875 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001877 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001878 default:
1879 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001881 }
1882 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883}
1884
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001886 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301888 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001889 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001891 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301892 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001894 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001897 //store UniPort with the System-PortNumber key
1898 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001899 if !dh.reconciling {
1900 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001901 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1902 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001903 } //error logging already within UniPort method
1904 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001906 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001907 }
1908 }
1909}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001910
mpagenko3af1f032020-06-10 08:53:41 +00001911// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001912func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001913 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301914 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001915 // with following remark:
1916 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1917 // # load on the core
1918
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001919 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001920
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001921 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001922 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301923 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301925 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001926 if !dh.reconciling {
1927 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928 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 +00001929 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001930 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001932 }
mpagenko3af1f032020-06-10 08:53:41 +00001933 }
1934 }
1935}
1936
1937// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001939 // compare enableUniPortStateUpdate() above
1940 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1941 for uniNo, uniPort := range dh.uniEntityMap {
1942 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301943 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301945 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001946 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001947 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 +00001948 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001949 }
1950}
1951
1952// ONU_Active/Inactive announcement on system KAFKA bus
1953// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001955 var de voltha.DeviceEvent
1956 eventContext := make(map[string]string)
1957 //Populating event context
1958 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001960 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301962 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001963 }
1964 oltSerialNumber := parentDevice.SerialNumber
1965
1966 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1967 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1968 eventContext["serial-number"] = dh.device.SerialNumber
1969 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301970 eventContext["device_id"] = aDeviceID
1971 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001973 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001974
1975 /* Populating device event body */
1976 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301977 de.ResourceId = aDeviceID
1978 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001979 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1980 de.Description = fmt.Sprintf("%s Event - %s - %s",
1981 cEventObjectType, cOnuActivatedEvent, "Raised")
1982 } else {
1983 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1984 de.Description = fmt.Sprintf("%s Event - %s - %s",
1985 cEventObjectType, cOnuActivatedEvent, "Cleared")
1986 }
1987 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1989 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301990 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001991 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301993 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001994}
1995
Himani Chawla4d908332020-08-31 12:30:20 +05301996// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001998 chLSFsm := make(chan Message, 2048)
1999 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302000 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002002 sFsmName = "LockStateFSM"
2003 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002005 sFsmName = "UnLockStateFSM"
2006 }
mpagenko3af1f032020-06-10 08:53:41 +00002007
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002009 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002011 return
2012 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002014 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002015 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302016 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002017 dh.pLockStateFsm = pLSFsm
2018 } else {
2019 dh.pUnlockStateFsm = pLSFsm
2020 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002022 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002024 }
2025}
2026
2027// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002028func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002029 /* Uni Port lock/unlock procedure -
2030 ***** should run via 'adminDone' state and generate the argument requested event *****
2031 */
2032 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302033 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002034 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2035 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2036 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002037 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302038 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002039 }
2040 } else {
2041 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2042 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2043 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002044 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302045 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002046 }
2047 }
2048 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002049 if pLSStatemachine.Is(uniStDisabled) {
2050 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002052 // maybe try a FSM reset and then again ... - TODO!!!
2053 } else {
2054 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002056 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002057 }
2058 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002060 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002061 // maybe try a FSM reset and then again ... - TODO!!!
2062 }
2063 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002065 // maybe try a FSM reset and then again ... - TODO!!!
2066 }
2067}
2068
Himani Chawla6d2ae152020-09-02 13:11:20 +05302069//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002071 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002073 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002074 kvbackend := &db.Backend{
2075 Client: dh.pOpenOnuAc.kvClient,
2076 StoreType: dh.pOpenOnuAc.KVStoreType,
2077 /* address config update acc. to [VOL-2736] */
2078 Address: addr,
2079 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2080 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002081
mpagenkoaf801632020-07-03 10:00:42 +00002082 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002083}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302085 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002086
mpagenkodff5dda2020-08-28 11:52:01 +00002087 for _, field := range flow.GetOfbFields(apFlowItem) {
2088 switch field.Type {
2089 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2090 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002092 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2093 }
mpagenko01e726e2020-10-23 09:45:29 +00002094 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002095 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2096 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302097 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002098 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302099 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2100 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002101 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2102 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002103 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2104 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302105 return
mpagenkodff5dda2020-08-28 11:52:01 +00002106 }
2107 }
mpagenko01e726e2020-10-23 09:45:29 +00002108 */
mpagenkodff5dda2020-08-28 11:52:01 +00002109 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2110 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302111 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002112 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302113 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002114 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302115 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002116 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302118 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002119 }
2120 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2121 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302122 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002124 "PCP": loAddPcp})
2125 }
2126 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2127 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002128 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002129 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2130 }
2131 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2132 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002134 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2135 }
2136 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2137 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002139 "IPv4-DST": field.GetIpv4Dst()})
2140 }
2141 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2142 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002143 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002144 "IPv4-SRC": field.GetIpv4Src()})
2145 }
2146 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2147 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002149 "Metadata": field.GetTableMetadata()})
2150 }
2151 /*
2152 default:
2153 {
2154 //all other entires ignored
2155 }
2156 */
2157 }
2158 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302159}
mpagenkodff5dda2020-08-28 11:52:01 +00002160
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002162 for _, action := range flow.GetActions(apFlowItem) {
2163 switch action.Type {
2164 /* not used:
2165 case of.OfpActionType_OFPAT_OUTPUT:
2166 {
mpagenko01e726e2020-10-23 09:45:29 +00002167 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002168 "Output": action.GetOutput()})
2169 }
2170 */
2171 case of.OfpActionType_OFPAT_PUSH_VLAN:
2172 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002173 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002174 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2175 }
2176 case of.OfpActionType_OFPAT_SET_FIELD:
2177 {
2178 pActionSetField := action.GetSetField()
2179 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002181 "OxcmClass": pActionSetField.Field.OxmClass})
2182 }
2183 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302184 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302186 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002187 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302188 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302190 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002191 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002193 "Type": pActionSetField.Field.GetOfbField().Type})
2194 }
2195 }
2196 /*
2197 default:
2198 {
2199 //all other entires ignored
2200 }
2201 */
2202 }
2203 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302204}
2205
2206//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2209 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2210 var loAddPcp, loSetPcp uint8
2211 var loIPProto uint32
2212 /* the TechProfileId is part of the flow Metadata - compare also comment within
2213 * OLT-Adapter:openolt_flowmgr.go
2214 * Metadata 8 bytes:
2215 * Most Significant 2 Bytes = Inner VLAN
2216 * Next 2 Bytes = Tech Profile ID(TPID)
2217 * Least Significant 4 Bytes = Port ID
2218 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2219 * subscriber related flows.
2220 */
2221
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302223 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302225 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002226 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302227 }
mpagenko551a4d42020-12-08 18:09:20 +00002228 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002229 loCookie := apFlowItem.GetCookie()
2230 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002232 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302233
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002235 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302236 if loIPProto == 2 {
2237 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2238 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002239 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2240 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302241 return nil
2242 }
mpagenko01e726e2020-10-23 09:45:29 +00002243 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002245
2246 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002248 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2249 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2250 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2251 //TODO!!: Use DeviceId within the error response to rwCore
2252 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002253 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002254 }
2255 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002257 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2258 } else {
2259 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2260 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2261 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302262 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002263 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002265 }
mpagenko9a304ea2020-12-16 15:54:01 +00002266
2267 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2268 dh.lockVlanConfig.Lock()
2269 defer dh.lockVlanConfig.Unlock()
2270 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302271 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002273 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002274 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002275 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002276 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002277}
2278
2279//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002281 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2282 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2283 //no extra check is done on the rule parameters
2284 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2285 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2286 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2287 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002288 // - 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 +00002289 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002291
2292 /* TT related temporary workaround - should not be needed anymore
2293 for _, field := range flow.GetOfbFields(apFlowItem) {
2294 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2295 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002296 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002297 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2298 if loIPProto == 2 {
2299 // 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 +00002300 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002301 log.Fields{"device-id": dh.deviceID})
2302 return nil
2303 }
2304 }
2305 } //for all OfbFields
2306 */
2307
mpagenko9a304ea2020-12-16 15:54:01 +00002308 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2309 dh.lockVlanConfig.Lock()
2310 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002311 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002313 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002314 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002315 log.Fields{"device-id": dh.deviceID})
2316 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002317 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002318 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002319
mpagenko01e726e2020-10-23 09:45:29 +00002320 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002321}
2322
Himani Chawla26e555c2020-08-31 12:30:20 +05302323// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002324// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002325func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002326 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002327 chVlanFilterFsm := make(chan Message, 2048)
2328
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002330 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302332 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002333 }
2334
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002336 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2337 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002338 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302339 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002340 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2341 if pVlanFilterStatemachine != nil {
2342 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2343 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002346 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302347 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302349 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2350 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002351 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002352 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002353 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302354 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002355 }
2356 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002357 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002358 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302359 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002360 }
2361 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002363 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302364 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002365 }
2366 return nil
2367}
2368
mpagenkofc4f56e2020-11-04 17:17:49 +00002369//VerifyVlanConfigRequest checks on existence of a given uniPort
2370// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002371func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002372 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2373 var pCurrentUniPort *onuUniPort
2374 for _, uniPort := range dh.uniEntityMap {
2375 // only if this port is validated for operState transfer
2376 if uniPort.uniID == uint8(aUniID) {
2377 pCurrentUniPort = uniPort
2378 break //found - end search loop
2379 }
2380 }
2381 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002383 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2384 return
2385 }
mpagenko551a4d42020-12-08 18:09:20 +00002386 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002387}
2388
mpagenkodff5dda2020-08-28 11:52:01 +00002389//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002390func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002391 //TODO!! verify and start pending flow configuration
2392 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2393 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302394 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002395 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2396 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2397 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002398 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2399 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2400 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2401 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2402 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2403 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2404 } else {
2405 /***** UniVlanConfigFsm continued */
2406 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2407 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2408 "UniPort": apUniPort.portNo})
2409 }
2410 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2411 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2412 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2413 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2414 } else {
2415 /***** UniVlanConfigFsm continued */
2416 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2417 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2418 "UniPort": apUniPort.portNo})
2419 }
mpagenkodff5dda2020-08-28 11:52:01 +00002420 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002421 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2422 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002423 "UniPort": apUniPort.portNo})
2424 }
2425 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002426 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2427 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2428 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002429 }
2430 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002431 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002432 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002433 }
mpagenkodff5dda2020-08-28 11:52:01 +00002434 } // else: nothing to do
2435}
2436
2437//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2438// 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 +00002439func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2440 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002441 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2442 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302443 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002444}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002445
2446//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2447//available for potential reconcilement
2448
dbainbri4d3a0dc2020-12-02 00:33:42 +00002449func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002450
2451 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002452 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002453 return nil
2454 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002456
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002458 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002459 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002460 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2461 }
2462 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2463
2464 pDevEntry.lockOnuKVStoreMutex()
2465 defer pDevEntry.unlockOnuKVStoreMutex()
2466
2467 // deadline context to ensure completion of background routines waited for
2468 //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 +05302469 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002470 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2471
2472 pDevEntry.resetKvProcessingErrorIndication()
2473 var wg sync.WaitGroup
2474 wg.Add(1) // for the 1 go routine to finish
2475
dbainbri4d3a0dc2020-12-02 00:33:42 +00002476 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2477 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002478
2479 return pDevEntry.getKvProcessingErrorIndication()
2480}
2481
dbainbri4d3a0dc2020-12-02 00:33:42 +00002482func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002483 defer cancel() //ensure termination of context (may be pro forma)
2484 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002486 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002487}
2488
dbainbri4d3a0dc2020-12-02 00:33:42 +00002489func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002490
2491 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002492 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002493 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2495 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002496 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002497 return err
2498 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002500 return nil
2501 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002503 return nil
2504}
2505
dbainbri4d3a0dc2020-12-02 00:33:42 +00002506func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2507 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002508 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002509 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002510 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2511 }
2512 pDevEntry.lockOnuKVStoreMutex()
2513 defer pDevEntry.unlockOnuKVStoreMutex()
2514
2515 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2516 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2517
2518 pDevEntry.resetKvProcessingErrorIndication()
2519 var wg sync.WaitGroup
2520 wg.Add(1) // for the 1 go routine to finish
2521
2522 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002524
2525 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002527 return err
2528 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002529 return nil
2530}
2531
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002532func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2533 var errStr string = ""
2534 for _, err := range errS {
2535 if err != nil {
2536 errStr = errStr + err.Error() + " "
2537 }
2538 }
2539 if errStr != "" {
2540 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2541 }
2542 return nil
2543}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002544
2545// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2546func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2547 dh.lockDevice.RLock()
2548 defer dh.lockDevice.RUnlock()
2549 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2550 return uniPort.entityID, nil
2551 }
2552 return 0, errors.New("error-fetching-uni-port")
2553}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002554
2555// updatePmConfig updates the pm metrics config.
2556func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
2557 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
2558
2559 // TODO: Currently support only updating the PM Sampling Frequency
2560 if pmConfigs.DefaultFreq != dh.pmMetrics.ToPmConfigs().DefaultFreq {
2561 dh.pmMetrics.UpdateFrequency(pmConfigs.DefaultFreq)
2562 logger.Debugw(ctx, "frequency-updated--new-frequency", log.Fields{"device-id": dh.deviceID, "frequency": dh.pmMetrics.ToPmConfigs().DefaultFreq})
2563 } else {
2564 logger.Debugw(ctx, "new-frequency-same-as-old--not-updating", log.Fields{"frequency": pmConfigs.DefaultFreq})
2565 }
2566}
2567
2568func (dh *deviceHandler) startCollector(ctx context.Context) {
2569 logger.Debugf(ctx, "startingCollector")
2570
2571 // Start routine to process OMCI GET Responses
2572 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
2573
2574 for {
2575 select {
2576 case <-dh.stopCollector:
2577 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2578 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2579 return
2580 case <-time.After(time.Duration(dh.pmMetrics.ToPmConfigs().DefaultFreq) * time.Second):
2581 go func() {
2582 logger.Debug(ctx, "startCollector before collecting optical metrics")
2583 metricInfo := dh.pOnuMetricsMgr.collectOpticalMetrics(ctx)
2584 dh.pOnuMetricsMgr.publishMetrics(ctx, metricInfo)
2585 }()
2586
2587 go func() {
2588 logger.Debug(ctx, "startCollector before collecting uni metrics")
2589 metricInfo := dh.pOnuMetricsMgr.collectUniStatusMetrics(ctx)
2590 dh.pOnuMetricsMgr.publishMetrics(ctx, metricInfo)
2591 }()
2592 }
2593 }
2594}