blob: c014ae4c5a291c0f4131bb229a929ba8873d2b6e [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/hex"
23 "errors"
24 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
34 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053035 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000036 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v4/pkg/log"
38 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050039 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000040 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
41 "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v4/go/openolt"
45 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000046)
47
48/*
49// Constants for number of retries and for timeout
50const (
51 MaxRetry = 10
52 MaxTimeOutInMs = 500
53)
54*/
55
mpagenko1cc3cb42020-07-27 15:24:38 +000056const (
57 // events of Device FSM
58 devEvDeviceInit = "devEvDeviceInit"
59 devEvGrpcConnected = "devEvGrpcConnected"
60 devEvGrpcDisconnected = "devEvGrpcDisconnected"
61 devEvDeviceUpInd = "devEvDeviceUpInd"
62 devEvDeviceDownInd = "devEvDeviceDownInd"
63)
64const (
65 // states of Device FSM
66 devStNull = "devStNull"
67 devStDown = "devStDown"
68 devStInit = "devStInit"
69 devStConnected = "devStConnected"
70 devStUp = "devStUp"
71)
72
Holger Hildebrandt24d51952020-05-04 14:03:42 +000073//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
74const (
Himani Chawla4d908332020-08-31 12:30:20 +053075 pon = voltha.EventSubCategory_PON
76 //olt = voltha.EventSubCategory_OLT
77 //ont = voltha.EventSubCategory_ONT
78 //onu = voltha.EventSubCategory_ONU
79 //nni = voltha.EventSubCategory_NNI
80 //service = voltha.EventCategory_SERVICE
81 //security = voltha.EventCategory_SECURITY
82 equipment = voltha.EventCategory_EQUIPMENT
83 //processing = voltha.EventCategory_PROCESSING
84 //environment = voltha.EventCategory_ENVIRONMENT
85 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000086)
87
88const (
89 cEventObjectType = "ONU"
90)
91const (
92 cOnuActivatedEvent = "ONU_ACTIVATED"
93)
94
Holger Hildebrandt10d98192021-01-27 15:29:31 +000095type usedOmciConfigFsms int
96
97const (
98 cUploadFsm usedOmciConfigFsms = iota
99 cDownloadFsm
100 cUniLockFsm
101 cUniUnLockFsm
102 cAniConfigFsm
103 cUniVlanConfigFsm
104)
105
106type idleCheckStruct struct {
107 idleCheckFunc func(*deviceHandler, context.Context, string) bool
108 idleState string
109}
110
111var fsmIdleStateFuncMap = map[usedOmciConfigFsms]idleCheckStruct{
112 cUploadFsm: {(*deviceHandler).mibUploadFsmInIdleState, cMibUlFsmIdleState},
113 cDownloadFsm: {(*deviceHandler).mibDownloadFsmInIdleState, cMibDlFsmIdleState},
114 cUniLockFsm: {(*deviceHandler).devUniLockFsmInIdleState, cUniFsmIdleState},
115 cUniUnLockFsm: {(*deviceHandler).devUniUnlockFsmInIdleState, cUniFsmIdleState},
116 cAniConfigFsm: {(*deviceHandler).devAniConfigFsmInIdleState, cAniFsmIdleState},
117 cUniVlanConfigFsm: {(*deviceHandler).devUniVlanConfigFsmInIdleState, cVlanFsmIdleState},
118}
119
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000120const (
121 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000122 drUnset = 0
123 drActivatingOnu = 1
124 drStartingOpenomci = 2
125 drDiscoveryMibsyncComplete = 3
126 drInitialMibDownloaded = 4
127 drTechProfileConfigDownloadSuccess = 5
128 drOmciFlowsPushed = 6
129 drOmciAdminLock = 7
130 drOnuReenabled = 8
131 drStoppingOpenomci = 9
132 drRebooting = 10
133 drOmciFlowsDeleted = 11
134 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000135)
136
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000137var deviceReasonMap = map[uint8]string{
138 drUnset: "unset",
139 drActivatingOnu: "activating-onu",
140 drStartingOpenomci: "starting-openomci",
141 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
142 drInitialMibDownloaded: "initial-mib-downloaded",
143 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
144 drOmciFlowsPushed: "omci-flows-pushed",
145 drOmciAdminLock: "omci-admin-lock",
146 drOnuReenabled: "onu-reenabled",
147 drStoppingOpenomci: "stopping-openomci",
148 drRebooting: "rebooting",
149 drOmciFlowsDeleted: "omci-flows-deleted",
150 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
151}
152
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153//deviceHandler will interact with the ONU ? device.
154type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155 deviceID string
156 DeviceType string
157 adminState string
158 device *voltha.Device
159 logicalDeviceID string
160 ProxyAddressID string
161 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530162 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000163 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000165 coreProxy adapterif.CoreProxy
166 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530167 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000168
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800169 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800170
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 pOpenOnuAc *OpenONUAC
172 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530173 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000174 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000175 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530176 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800177 pOnuMetricsMgr *onuMetricsManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178 exitChannel chan int
179 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000180 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000181 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530182 pLockStateFsm *lockStateFsm
183 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000185 //flowMgr *OpenOltFlowMgr
186 //eventMgr *OpenOltEventMgr
187 //resourceMgr *rsrcMgr.OpenOltResourceMgr
188
189 //discOnus sync.Map
190 //onus sync.Map
191 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000192 collectorIsRunning bool
193 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000194 stopCollector chan bool
195 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000196 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000197 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000198 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
199 reconciling bool
200 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201}
202
Himani Chawla6d2ae152020-09-02 13:11:20 +0530203//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530204func 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 +0530205 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 dh.coreProxy = cp
207 dh.AdapterProxy = ap
208 dh.EventProxy = ep
209 cloned := (proto.Clone(device)).(*voltha.Device)
210 dh.deviceID = cloned.Id
211 dh.DeviceType = cloned.Type
212 dh.adminState = "up"
213 dh.device = cloned
214 dh.pOpenOnuAc = adapter
215 dh.exitChannel = make(chan int, 1)
216 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000217 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000218 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219 dh.stopCollector = make(chan bool, 2)
220 dh.stopHeartbeatCheck = make(chan bool, 2)
221 //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 +0000222 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530223 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000224 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000225 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000226 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000227 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800229 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
230 dh.pmConfigs = cloned.PmConfigs
231 } /* else {
232 // will be populated when onu_metrics_mananger is initialized.
233 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800234
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 // Device related state machine
236 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000237 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000239 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
240 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
241 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
242 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
243 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 },
245 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000246 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
247 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
248 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
249 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
250 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
251 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
252 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
253 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254 },
255 )
mpagenkoaf801632020-07-03 10:00:42 +0000256
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 return &dh
258}
259
Himani Chawla6d2ae152020-09-02 13:11:20 +0530260// start save the device to the data model
261func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000263 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000264 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000265}
266
Himani Chawla4d908332020-08-31 12:30:20 +0530267/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530269func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 logger.Debug("stopping-device-handler")
271 dh.exitChannel <- 1
272}
Himani Chawla4d908332020-08-31 12:30:20 +0530273*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000274
275// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530276// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277
Himani Chawla6d2ae152020-09-02 13:11:20 +0530278//adoptOrReconcileDevice adopts the OLT device
279func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281
dbainbri4d3a0dc2020-12-02 00:33:42 +0000282 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000283 if dh.pDeviceStateFsm.Is(devStNull) {
284 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800288 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
289 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800290 // Now, set the initial PM configuration for that device
291 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
292 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
293 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800294 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 }
298
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299}
300
mpagenko057889c2021-01-21 16:51:58 +0000301func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530302 msgBody := msg.GetBody()
303 omciMsg := &ic.InterAdapterOmciMessage{}
304 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530306 "device-id": dh.deviceID, "error": err})
307 return err
308 }
309
310 //assuming omci message content is hex coded!
311 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530313 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
314 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000315 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530316 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000317 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000318 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000319 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 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 +0530321 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000323 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530324}
325
Himani Chawla6d2ae152020-09-02 13:11:20 +0530326func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530328 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000329
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000331
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000333 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000334 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000335 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
336 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530337 if dh.pOnuTP == nil {
338 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000341 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000343 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000345 "device-state": deviceReasonMap[dh.deviceReason]})
346 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000348 //previous state test here was just this one, now extended for more states to reject the SetRequest:
349 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
350 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530351
352 msgBody := msg.GetBody()
353 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
354 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 "device-id": dh.deviceID, "error": err})
357 return err
358 }
359
360 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000361 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
362 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364 defer dh.pOnuTP.unlockTpProcMutex()
365 pDevEntry.lockOnuKVStoreMutex()
366 defer pDevEntry.unlockOnuKVStoreMutex()
367
368 if techProfMsg.UniId > 255 {
369 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
370 techProfMsg.UniId, dh.deviceID))
371 }
372 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
374 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800376 return err
377 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 // if there has been some change for some uni TechProfilePath
381 //in order to allow concurrent calls to other dh instances we do not wait for execution here
382 //but doing so we can not indicate problems to the caller (who does what with that then?)
383 //by now we just assume straightforward successful execution
384 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
385 // possible problems to the caller later autonomously
386
387 // deadline context to ensure completion of background routines waited for
388 //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 +0530389 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 dctx, cancel := context.WithDeadline(context.Background(), deadline)
391
Girish Gowdra041dcb32020-11-16 16:54:30 -0800392 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 pDevEntry.resetKvProcessingErrorIndication()
394
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 var wg sync.WaitGroup
396 wg.Add(2) // for the 2 go routines to finish
397 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
399 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
400 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
Girish Gowdra041dcb32020-11-16 16:54:30 -0800402 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 return nil
406}
407
Himani Chawla6d2ae152020-09-02 13:11:20 +0530408func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000409 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 msg *ic.InterAdapterMessage) error {
411
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000413
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
418 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 if dh.pOnuTP == nil {
420 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 }
425
426 msgBody := msg.GetBody()
427 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
428 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530430 "device-id": dh.deviceID, "error": err})
431 return err
432 }
433
434 //compare TECH_PROFILE_DOWNLOAD_REQUEST
435 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 defer dh.pOnuTP.unlockTpProcMutex()
437 pDevEntry.lockOnuKVStoreMutex()
438 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530439
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 if delGemPortMsg.UniId > 255 {
441 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
442 delGemPortMsg.UniId, dh.deviceID))
443 }
444 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800445 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
446 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000447 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 -0800448 return err
449 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530450
mpagenkofc4f56e2020-11-04 17:17:49 +0000451 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452
mpagenkofc4f56e2020-11-04 17:17:49 +0000453 // deadline context to ensure completion of background routines waited for
454 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
455 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456
Girish Gowdra041dcb32020-11-16 16:54:30 -0800457 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000458
mpagenkofc4f56e2020-11-04 17:17:49 +0000459 var wg sync.WaitGroup
460 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000462 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000464
Girish Gowdra041dcb32020-11-16 16:54:30 -0800465 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530466}
467
Himani Chawla6d2ae152020-09-02 13:11:20 +0530468func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000469 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000473
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000475 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
478 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 if dh.pOnuTP == nil {
480 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 }
485
486 msgBody := msg.GetBody()
487 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
488 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 "device-id": dh.deviceID, "error": err})
491 return err
492 }
493
494 //compare TECH_PROFILE_DOWNLOAD_REQUEST
495 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000496 defer dh.pOnuTP.unlockTpProcMutex()
497 pDevEntry.lockOnuKVStoreMutex()
498 defer pDevEntry.unlockOnuKVStoreMutex()
499
500 if delTcontMsg.UniId > 255 {
501 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
502 delTcontMsg.UniId, dh.deviceID))
503 }
504 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 tpPath := delTcontMsg.TpPath
506 tpID, err := GetTpIDFromTpPath(tpPath)
507 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800509 return err
510 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530514 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 dctx, cancel := context.WithDeadline(context.Background(), deadline)
516
Girish Gowdra041dcb32020-11-16 16:54:30 -0800517 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518 pDevEntry.resetKvProcessingErrorIndication()
519
Himani Chawla26e555c2020-08-31 12:30:20 +0530520 var wg sync.WaitGroup
521 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000522 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530523 cResourceTcont, delTcontMsg.AllocId, &wg)
524 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
526 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527
Girish Gowdra041dcb32020-11-16 16:54:30 -0800528 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 return nil
531}
532
Himani Chawla6d2ae152020-09-02 13:11:20 +0530533//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000534// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
535// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000537 msgID := msg.Header.Id
538 msgType := msg.Header.Type
539 fromTopic := msg.Header.FromTopic
540 toTopic := msg.Header.ToTopic
541 toDeviceID := msg.Header.ToDeviceId
542 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000543 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000544 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
545
546 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000547 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000548 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
549 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000550 {
mpagenko057889c2021-01-21 16:51:58 +0000551 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000552 }
mpagenkoaf801632020-07-03 10:00:42 +0000553 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
554 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000556 }
557 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
558 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000559 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000560
mpagenkoaf801632020-07-03 10:00:42 +0000561 }
562 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
563 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000565 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000566 default:
567 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000569 "msgType": msg.Header.Type, "device-id": dh.deviceID})
570 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 }
572 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000573}
574
mpagenkodff5dda2020-08-28 11:52:01 +0000575//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
577 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000578 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000580
mpagenko01e726e2020-10-23 09:45:29 +0000581 var retError error = nil
582 //Remove flows (always remove flows first - remove old and add new with same cookie may be part of the same request)
mpagenkodff5dda2020-08-28 11:52:01 +0000583 if apOfFlowChanges.ToRemove != nil {
584 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000585 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000587 "device-id": dh.deviceID})
588 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000589 continue
590 }
591 flowInPort := flow.GetInPort(flowItem)
592 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000594 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
595 continue
596 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000597 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000598 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000600 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000601 continue
602 } else {
603 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530604 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000605 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
606 loUniPort = uniPort
607 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000609 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
610 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
611 flowInPort, dh.deviceID)
612 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000613 }
614 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000616 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000617 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000619 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000620 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000622 log.Fields{"device-id": dh.deviceID, "error": err})
623 retError = err
624 continue
625 //return err
626 } else { // if last setting succeeds, overwrite possibly previously set error
627 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000628 }
629 }
630 }
631 }
mpagenko01e726e2020-10-23 09:45:29 +0000632 if apOfFlowChanges.ToAdd != nil {
633 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
634 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000635 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000636 "device-id": dh.deviceID})
637 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
638 continue
639 }
640 flowInPort := flow.GetInPort(flowItem)
641 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000643 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
644 continue
645 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
646 } else if flowInPort == dh.ponPortNumber {
647 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000649 "device-id": dh.deviceID, "inPort": flowInPort})
650 continue
651 } else {
652 // this is the relevant upstream flow
653 var loUniPort *onuUniPort
654 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
655 loUniPort = uniPort
656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000658 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
659 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
660 flowInPort, dh.deviceID)
661 continue
662 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
663 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000664 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
665 // if not, we just throw some error here to have an indication about that, if we really need to support that
666 // then we would need to create some means to activate the internal stored flows
667 // after the device gets active automatically (and still with its dependency to the TechProfile)
668 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
669 // also abort for the other still possible flows here
670 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000672 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000673 return fmt.Errorf("improper device state on device %s", dh.deviceID)
674 }
675
mpagenko01e726e2020-10-23 09:45:29 +0000676 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000678 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
679 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000681 //try next flow after processing error
682 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000684 log.Fields{"device-id": dh.deviceID, "error": err})
685 retError = err
686 continue
687 //return err
688 } else { // if last setting succeeds, overwrite possibly previously set error
689 retError = nil
690 }
691 }
692 }
693 }
694 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000695}
696
Himani Chawla6d2ae152020-09-02 13:11:20 +0530697//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000698//following are the expected device states after this activity:
699//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
700// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
702 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000703
mpagenko900ee4b2020-10-12 11:56:34 +0000704 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000705 //note that disableDevice sequences in some 'ONU active' state may yield also
706 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000707 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000708 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000709 //disable-device shall be just a UNi/ONU-G related admin state setting
710 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000711
mpagenkofc4f56e2020-11-04 17:17:49 +0000712 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000713 // disable UNI ports/ONU
714 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
715 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000717 } else { //LockStateFSM already init
718 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000720 }
721 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000723 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000725 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
726 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000728 }
mpagenko01e726e2020-10-23 09:45:29 +0000729 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000730
731 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000733 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300734 }
735}
736
Himani Chawla6d2ae152020-09-02 13:11:20 +0530737//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
739 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000740
mpagenkofc4f56e2020-11-04 17:17:49 +0000741 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
742 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
743 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
744 // for real ONU's that should have nearly no influence
745 // Note that for real ONU's there is anyway a problematic situation with following sequence:
746 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
747 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
748 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
749 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
750
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000751 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000752 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000753 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000755 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000756 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000757 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000758 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300759}
760
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
762 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000763
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000765 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000767 return
768 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000770 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000772 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000774 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000775 dh.reconciling = false
776 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000777 }
Himani Chawla4d908332020-08-31 12:30:20 +0530778 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000779 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
780 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
781 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
782 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000784}
785
dbainbri4d3a0dc2020-12-02 00:33:42 +0000786func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
787 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000788
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 return
793 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 dh.pOnuTP.lockTpProcMutex()
795 defer dh.pOnuTP.unlockTpProcMutex()
796
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000797 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000799 log.Fields{"device-id": dh.deviceID})
800 dh.reconciling = false
801 return
802 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000804 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
805 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000807 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
808 dh.reconciling = false
809 return
810 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800811 for tpID := range uniData.PersTpPathMap {
812 // deadline context to ensure completion of background routines waited for
813 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
814 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000816
Girish Gowdra041dcb32020-11-16 16:54:30 -0800817 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
818 var wg sync.WaitGroup
819 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
821 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800822 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800824 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000826 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000828 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
829 dh.reconciling = false
830 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 }
832}
833
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
835 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000840 return
841 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000842 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000844 log.Fields{"device-id": dh.deviceID})
845 dh.reconciling = false
846 return
847 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000849 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
850 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000852 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
853 dh.reconciling = false
854 return
855 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 var uniPort *onuUniPort
857 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 return
862 }
863 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000865 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000868 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
869 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000874 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000875 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 }
878 }
879 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000880 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
883 dh.reconciling = false
884 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 }
886}
887
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
889 logger.Debugw(ctx, "reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890
891 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000892 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000893}
894
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
896 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000897
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000900 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000902 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000903 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000904 pDevEntry.lockOnuKVStoreMutex()
905 defer pDevEntry.unlockOnuKVStoreMutex()
906
907 // deadline context to ensure completion of background routines waited for
908 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +0530909 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000911
912 pDevEntry.resetKvProcessingErrorIndication()
913
914 var wg sync.WaitGroup
915 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
917 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000918
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000919 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000920 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921}
922
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
924 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300925 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300928 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530930 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000931 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530932 return err
933 }
mpagenko01e726e2020-10-23 09:45:29 +0000934
935 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000936 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000937
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000939 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300941 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000942 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300944 return err
945 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300947 return err
948 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000949 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000950 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
951 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
952 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
953 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300954 return nil
955}
956
mpagenkoc8bba412021-01-15 15:38:44 +0000957//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
958func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
959 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
960 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000961 //return success to comfort the core processing during integration
962 return nil
963 // TODO!!: also verify error response behavior
964 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000965}
966
Himani Chawla6d2ae152020-09-02 13:11:20 +0530967// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000968// #####################################################################################
969
970// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530971// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000972
dbainbri4d3a0dc2020-12-02 00:33:42 +0000973func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
974 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 +0000975}
976
977// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000979
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981 var err error
982
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000983 // populate what we know. rest comes later after mib sync
984 dh.device.Root = false
985 dh.device.Vendor = "OpenONU"
986 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000987 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000988 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000989
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000990 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000991
992 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
994 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530995 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000996 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000997 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000998 log.Fields{"device-id": dh.deviceID})
999 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001000
Himani Chawla4d908332020-08-31 12:30:20 +05301001 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001002 dh.ponPortNumber = dh.device.ParentPortNo
1003
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001004 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1005 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1006 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001007 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001008 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301009 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001010
1011 /*
1012 self._pon = PonPort.create(self, self._pon_port_number)
1013 self._pon.add_peer(self.parent_id, self._pon_port_number)
1014 self.logger.debug('adding-pon-port-to-agent',
1015 type=self._pon.get_port().type,
1016 admin_state=self._pon.get_port().admin_state,
1017 oper_status=self._pon.get_port().oper_status,
1018 )
1019 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001020 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001022 var ponPortNo uint32 = 1
1023 if dh.ponPortNumber != 0 {
1024 ponPortNo = dh.ponPortNumber
1025 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001026
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001027 pPonPort := &voltha.Port{
1028 PortNo: ponPortNo,
1029 Label: fmt.Sprintf("pon-%d", ponPortNo),
1030 Type: voltha.Port_PON_ONU,
1031 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301032 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001033 PortNo: ponPortNo}}, // Peer port is parent's port number
1034 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001035 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1036 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001037 e.Cancel(err)
1038 return
1039 }
1040 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001041 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001042 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001044}
1045
1046// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001048
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050 var err error
1051 /*
1052 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1053 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1054 return nil
1055 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001056 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1057 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001058 e.Cancel(err)
1059 return
1060 }
1061
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001062 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001064 // reconcilement will be continued after mib download is done
1065 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001066
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001067 /*
1068 ############################################################################
1069 # Setup Alarm handler
1070 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1071 device.serial_number)
1072 ############################################################################
1073 # Setup PM configuration for this device
1074 # Pass in ONU specific options
1075 kwargs = {
1076 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1077 'heartbeat': self.heartbeat,
1078 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1079 }
1080 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1081 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1082 self.logical_device_id, device.serial_number,
1083 grouped=True, freq_override=False, **kwargs)
1084 pm_config = self._pm_metrics.make_proto()
1085 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1086 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1087 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1088
1089 # Note, ONU ID and UNI intf set in add_uni_port method
1090 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1091 ani_ports=[self._pon])
1092
1093 # Code to Run OMCI Test Action
1094 kwargs_omci_test_action = {
1095 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1096 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1097 }
1098 serial_number = device.serial_number
1099 self._test_request = OmciTestRequest(self.core_proxy,
1100 self.omci_agent, self.device_id,
1101 AniG, serial_number,
1102 self.logical_device_id,
1103 exclusive=False,
1104 **kwargs_omci_test_action)
1105
1106 self.enabled = True
1107 else:
1108 self.logger.info('onu-already-activated')
1109 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001110
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001112}
1113
1114// doStateConnected get the device info and update to voltha core
1115// for comparison of the original method (not that easy to uncomment): compare here:
1116// voltha-openolt-adapter/adaptercore/device_handler.go
1117// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301121 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001122 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001123 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124}
1125
1126// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001127func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001128
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301130 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001131 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133
1134 /*
1135 // Synchronous call to update device state - this method is run in its own go routine
1136 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1137 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001138 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 +00001139 return err
1140 }
1141 return nil
1142 */
1143}
1144
1145// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001149 var err error
1150
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001151 device := dh.device
1152 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001153 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155 e.Cancel(err)
1156 return
1157 }
1158
1159 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001160 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001161 /*
1162 // Update the all ports state on that device to disable
1163 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001164 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001165 return er
1166 }
1167
1168 //Update the device oper state and connection status
1169 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1170 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1171 dh.device = cloned
1172
1173 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001174 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001175 return er
1176 }
1177
1178 //get the child device for the parent device
1179 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1180 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001181 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001182 return err
1183 }
1184 for _, onuDevice := range onuDevices.Items {
1185
1186 // Update onu state as down in onu adapter
1187 onuInd := oop.OnuIndication{}
1188 onuInd.OperState = "down"
1189 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1190 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1191 if er != nil {
1192 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001193 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001194 //Do not return here and continue to process other ONUs
1195 }
1196 }
1197 // * Discovered ONUs entries need to be cleared , since after OLT
1198 // is up, it starts sending discovery indications again* /
1199 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001200 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001201 return nil
1202 */
Himani Chawla4d908332020-08-31 12:30:20 +05301203 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001204 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206}
1207
Himani Chawla6d2ae152020-09-02 13:11:20 +05301208// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001209// #################################################################################
1210
1211// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301212// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001213
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001214//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001215func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001216 dh.lockDevice.RLock()
1217 pOnuDeviceEntry := dh.pOnuOmciDevice
1218 if aWait && pOnuDeviceEntry == nil {
1219 //keep the read sema short to allow for subsequent write
1220 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001221 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001222 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1223 // so it might be needed to wait here for that event with some timeout
1224 select {
1225 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001227 return nil
1228 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001230 // if written now, we can return the written value without sema
1231 return dh.pOnuOmciDevice
1232 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001233 }
mpagenko3af1f032020-06-10 08:53:41 +00001234 dh.lockDevice.RUnlock()
1235 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001236}
1237
Himani Chawla6d2ae152020-09-02 13:11:20 +05301238//setOnuDeviceEntry sets the ONU device entry within the handler
1239func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001240 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001241 dh.lockDevice.Lock()
1242 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001243 dh.pOnuOmciDevice = apDeviceEntry
1244 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001245 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001246}
1247
Himani Chawla6d2ae152020-09-02 13:11:20 +05301248//addOnuDeviceEntry creates a new ONU device or returns the existing
1249func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001251
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001253 if deviceEntry == nil {
1254 /* costum_me_map in python code seems always to be None,
1255 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1256 /* also no 'clock' argument - usage open ...*/
1257 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001258 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001259 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001260 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001261 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001262 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001263 // fire deviceEntry ready event to spread to possibly waiting processing
1264 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001266 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001268 }
1269 // might be updated with some error handling !!!
1270 return nil
1271}
1272
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1274 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001275 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1276
1277 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001278
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001280 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001282 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1283 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001284 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 if err := dh.storePersistentData(ctx); err != nil {
1286 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001287 log.Fields{"device-id": dh.deviceID, "err": err})
1288 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001289 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001290 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001292 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1293 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001295 }
1296 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001297 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001298 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001299
1300 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 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 +00001302 log.Fields{"device-id": dh.deviceID})
1303 dh.reconciling = false
1304 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001305 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001306 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1307 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1308 // 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 +00001309 // 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 +00001310 // so let's just try to keep it simple ...
1311 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001313 if err != nil || device == nil {
1314 //TODO: needs to handle error scenarios
1315 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1316 return errors.New("Voltha Device not found")
1317 }
1318 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001319
dbainbri4d3a0dc2020-12-02 00:33:42 +00001320 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001321 return err
mpagenko3af1f032020-06-10 08:53:41 +00001322 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001323
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001325
1326 /* this might be a good time for Omci Verify message? */
1327 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001328 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001329 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001330 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001331 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001332
1333 /* give the handler some time here to wait for the OMCi verification result
1334 after Timeout start and try MibUpload FSM anyway
1335 (to prevent stopping on just not supported OMCI verification from ONU) */
1336 select {
1337 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001338 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001339 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001341 }
1342
1343 /* In py code it looks earlier (on activate ..)
1344 # Code to Run OMCI Test Action
1345 kwargs_omci_test_action = {
1346 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1347 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1348 }
1349 serial_number = device.serial_number
1350 self._test_request = OmciTestRequest(self.core_proxy,
1351 self.omci_agent, self.device_id,
1352 AniG, serial_number,
1353 self.logical_device_id,
1354 exclusive=False,
1355 **kwargs_omci_test_action)
1356 ...
1357 # Start test requests after a brief pause
1358 if not self._test_request_started:
1359 self._test_request_started = True
1360 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1361 reactor.callLater(tststart, self._test_request.start_collector)
1362
1363 */
1364 /* which is then: in omci_test_request.py : */
1365 /*
1366 def start_collector(self, callback=None):
1367 """
1368 Start the collection loop for an adapter if the frequency > 0
1369
1370 :param callback: (callable) Function to call to collect PM data
1371 """
1372 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1373 if callback is None:
1374 callback = self.perform_test_omci
1375
1376 if self.lc is None:
1377 self.lc = LoopingCall(callback)
1378
1379 if self.default_freq > 0:
1380 self.lc.start(interval=self.default_freq / 10)
1381
1382 def perform_test_omci(self):
1383 """
1384 Perform the initial test request
1385 """
1386 ani_g_entities = self._device.configuration.ani_g_entities
1387 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1388 is not None else None
1389 self._entity_id = ani_g_entities_ids[0]
1390 self.logger.info('perform-test', entity_class=self._entity_class,
1391 entity_id=self._entity_id)
1392 try:
1393 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1394 result = yield self._device.omci_cc.send(frame)
1395 if not result.fields['omci_message'].fields['success_code']:
1396 self.logger.info('Self-Test Submitted Successfully',
1397 code=result.fields[
1398 'omci_message'].fields['success_code'])
1399 else:
1400 raise TestFailure('Test Failure: {}'.format(
1401 result.fields['omci_message'].fields['success_code']))
1402 except TimeoutError as e:
1403 self.deferred.errback(failure.Failure(e))
1404
1405 except Exception as e:
1406 self.logger.exception('perform-test-Error', e=e,
1407 class_id=self._entity_class,
1408 entity_id=self._entity_id)
1409 self.deferred.errback(failure.Failure(e))
1410
1411 */
1412
1413 // PM related heartbeat??? !!!TODO....
1414 //self._heartbeat.enabled = True
1415
mpagenko1cc3cb42020-07-27 15:24:38 +00001416 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1417 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1418 * 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 +05301419 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001420 */
1421 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001422 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001423 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001424 if pMibUlFsm.Is(ulStDisabled) {
1425 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 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 +00001427 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301428 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301430 //Determine ONU status and start/re-start MIB Synchronization tasks
1431 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001432 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301433 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001434 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 +00001435 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001436 }
Himani Chawla4d908332020-08-31 12:30:20 +05301437 } else {
1438 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 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 +00001440 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301441 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001443 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001444 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001446 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001447 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001448 }
1449 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001450 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001451 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001453
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001454 if !dh.getCollectorIsRunning() {
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!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001470 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471 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
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001523func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) 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 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001534 if includingMibSyncFsm {
1535 //the MibSync FSM might be active all the ONU-active time,
1536 // hence it must be stopped unconditionally
1537 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1538 if pMibUlFsm != nil {
1539 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1540 }
mpagenko900ee4b2020-10-12 11:56:34 +00001541 }
1542 //MibDownload may run
1543 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1544 if pMibDlFsm != nil {
1545 _ = pMibDlFsm.Event(dlEvReset)
1546 }
1547 //port lock/unlock FSM's may be active
1548 if dh.pUnlockStateFsm != nil {
1549 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1550 }
1551 if dh.pLockStateFsm != nil {
1552 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1553 }
1554 //techProfile related PonAniConfigFsm FSM may be active
1555 if dh.pOnuTP != nil {
1556 // should always be the case here
1557 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1558 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001559 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1560 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1561 }
mpagenko900ee4b2020-10-12 11:56:34 +00001562 }
1563 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001564 // reset the possibly existing VlanConfigFsm
1565 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1566 //VlanFilterFsm exists and was already started
1567 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1568 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001569 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001570 // no need to remove specific data
1571 pVlanFilterFsm.RequestClearPersistency(false)
1572 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001573 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1574 }
1575 }
1576 }
1577 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001578 if dh.getCollectorIsRunning() {
1579 // Stop collector routine
1580 dh.stopCollector <- true
1581 }
mpagenko900ee4b2020-10-12 11:56:34 +00001582 return nil
1583}
1584
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1586 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 +05301587
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1589 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001590 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001591 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001592 return
1593 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001594 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001595 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1596 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1597 for _, mgmtEntityID := range pptpInstKeys {
1598 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1599 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301601 i++
1602 }
1603 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301605 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001606 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1607 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301608 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001609 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301610 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301612 i++
1613 }
1614 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301616 }
1617 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301619 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001620 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1621 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1622 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1623 * disable/enable toggling here to allow traffic
1624 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1625 * like the py comment says:
1626 * # start by locking all the unis till mib sync and initial mib is downloaded
1627 * # this way we can capture the port down/up events when we are ready
1628 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301629
mpagenkoa40e99a2020-11-17 13:50:39 +00001630 // Init Uni Ports to Admin locked state
1631 // *** should generate UniLockStateDone event *****
1632 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001634 } else { //LockStateFSM already init
1635 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001637 }
1638}
1639
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1641 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301642 /* Mib download procedure -
1643 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1644 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001646 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001648 return
1649 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301650 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1651 if pMibDlFsm != nil {
1652 if pMibDlFsm.Is(dlStDisabled) {
1653 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 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 +05301655 // maybe try a FSM reset and then again ... - TODO!!!
1656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301658 // maybe use more specific states here for the specific download steps ...
1659 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301661 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301663 //Begin MIB data download (running autonomously)
1664 }
1665 }
1666 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001668 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301669 // maybe try a FSM reset and then again ... - TODO!!!
1670 }
1671 /***** Mib download started */
1672 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301674 }
1675}
1676
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1678 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301679 //initiate DevStateUpdate
1680 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001682 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301684 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1685 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301687 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301689 }
1690 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001692 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 return
1695 }
1696 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 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 +00001698 log.Fields{"device-id": dh.deviceID})
1699 dh.reconciling = false
1700 return
1701 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301703 log.Fields{"device-id": dh.deviceID})
1704 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001706 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301707 // *** should generate UniUnlockStateDone event *****
1708 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301710 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301711 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301713 }
1714}
1715
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1717 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301718
1719 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301721 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1723 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 return
1727 }
1728 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 if err := dh.storePersistentData(ctx); err != nil {
1730 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001731 log.Fields{"device-id": dh.deviceID, "err": err})
1732 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301733 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734 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 +05301735 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001737 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301738 }
1739}
1740
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1742 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001743 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001745 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1746 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001748 }
1749
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001751 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001753
1754 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001756
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001758 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001760 return
1761 }
1762 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 if err := dh.storePersistentData(ctx); err != nil {
1764 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001765 log.Fields{"device-id": dh.deviceID, "err": err})
1766 }
mpagenko900ee4b2020-10-12 11:56:34 +00001767}
1768
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1770 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001771 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001773 voltha.OperStatus_ACTIVE); err != nil {
1774 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001776 }
1777
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001779 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001780 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001782
1783 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001785
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001787 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789 return
1790 }
1791 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 if err := dh.storePersistentData(ctx); err != nil {
1793 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001794 log.Fields{"device-id": dh.deviceID, "err": err})
1795 }
mpagenko900ee4b2020-10-12 11:56:34 +00001796}
1797
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001799 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001801 // attention: the device reason update is done based on ONU-UNI-Port related activity
1802 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001803 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001804 // 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 +00001805 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301806 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001807 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001809 }
1810 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001812 // attention: the device reason update is done based on ONU-UNI-Port related activity
1813 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001814 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001815 // 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 +00001816 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001817 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001818 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301819}
1820
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1822 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001823 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301824 // attention: the device reason update is done based on ONU-UNI-Port related activity
1825 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301826
mpagenkofc4f56e2020-11-04 17:17:49 +00001827 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001828 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001829 // which may be the case from some previous actvity on another UNI Port of the ONU
1830 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001832 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001833 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001834 }
1835 }
1836 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001837 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001838 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001840 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301841 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001842 if err := dh.storePersistentData(ctx); err != nil {
1843 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1844 log.Fields{"device-id": dh.deviceID, "err": err})
1845 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301846}
1847
Himani Chawla6d2ae152020-09-02 13:11:20 +05301848//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301850 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001851 case MibDatabaseSync:
1852 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001854 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001855 case UniLockStateDone:
1856 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001858 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001859 case MibDownloadDone:
1860 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001862 }
1863 case UniUnlockStateDone:
1864 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001866 }
mpagenko900ee4b2020-10-12 11:56:34 +00001867 case UniEnableStateDone:
1868 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001870 }
1871 case UniDisableStateDone:
1872 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001874 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001875 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001876 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001878 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001879 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001880 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001882 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001883 default:
1884 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001886 }
1887 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001888}
1889
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001891 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301893 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001894 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301897 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001899 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001901 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001902 //store UniPort with the System-PortNumber key
1903 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001904 if !dh.reconciling {
1905 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1907 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001908 } //error logging already within UniPort method
1909 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001911 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001912 }
1913 }
1914}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001915
mpagenko3af1f032020-06-10 08:53:41 +00001916// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001917func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001918 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301919 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001920 // with following remark:
1921 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1922 // # load on the core
1923
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001924 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001925
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001926 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001927 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301928 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301930 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001931 if !dh.reconciling {
1932 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 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 +00001934 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001935 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001937 }
mpagenko3af1f032020-06-10 08:53:41 +00001938 }
1939 }
1940}
1941
1942// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001944 // compare enableUniPortStateUpdate() above
1945 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1946 for uniNo, uniPort := range dh.uniEntityMap {
1947 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301948 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301950 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001951 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 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 +00001953 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001954 }
1955}
1956
1957// ONU_Active/Inactive announcement on system KAFKA bus
1958// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001960 var de voltha.DeviceEvent
1961 eventContext := make(map[string]string)
1962 //Populating event context
1963 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001965 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301967 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001968 }
1969 oltSerialNumber := parentDevice.SerialNumber
1970
1971 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1972 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1973 eventContext["serial-number"] = dh.device.SerialNumber
1974 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301975 eventContext["device_id"] = aDeviceID
1976 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001978 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001979
1980 /* Populating device event body */
1981 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301982 de.ResourceId = aDeviceID
1983 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001984 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1985 de.Description = fmt.Sprintf("%s Event - %s - %s",
1986 cEventObjectType, cOnuActivatedEvent, "Raised")
1987 } else {
1988 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1989 de.Description = fmt.Sprintf("%s Event - %s - %s",
1990 cEventObjectType, cOnuActivatedEvent, "Cleared")
1991 }
1992 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1994 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301995 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001996 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301998 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001999}
2000
Himani Chawla4d908332020-08-31 12:30:20 +05302001// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002003 chLSFsm := make(chan Message, 2048)
2004 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302005 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002006 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002007 sFsmName = "LockStateFSM"
2008 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002010 sFsmName = "UnLockStateFSM"
2011 }
mpagenko3af1f032020-06-10 08:53:41 +00002012
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002014 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002016 return
2017 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002018 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002019 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002020 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302021 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002022 dh.pLockStateFsm = pLSFsm
2023 } else {
2024 dh.pUnlockStateFsm = pLSFsm
2025 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002027 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002028 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002029 }
2030}
2031
2032// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002034 /* Uni Port lock/unlock procedure -
2035 ***** should run via 'adminDone' state and generate the argument requested event *****
2036 */
2037 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302038 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002039 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2040 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2041 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002042 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302043 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002044 }
2045 } else {
2046 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2047 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2048 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002049 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302050 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002051 }
2052 }
2053 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002054 if pLSStatemachine.Is(uniStDisabled) {
2055 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002057 // maybe try a FSM reset and then again ... - TODO!!!
2058 } else {
2059 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002061 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002062 }
2063 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002065 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002066 // maybe try a FSM reset and then again ... - TODO!!!
2067 }
2068 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002069 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002070 // maybe try a FSM reset and then again ... - TODO!!!
2071 }
2072}
2073
Himani Chawla6d2ae152020-09-02 13:11:20 +05302074//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002075func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002076
2077 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002078 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002079 kvbackend := &db.Backend{
2080 Client: dh.pOpenOnuAc.kvClient,
2081 StoreType: dh.pOpenOnuAc.KVStoreType,
2082 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002083 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002084 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2085 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002086
mpagenkoaf801632020-07-03 10:00:42 +00002087 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002088}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302090 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002091
mpagenkodff5dda2020-08-28 11:52:01 +00002092 for _, field := range flow.GetOfbFields(apFlowItem) {
2093 switch field.Type {
2094 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2095 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002097 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2098 }
mpagenko01e726e2020-10-23 09:45:29 +00002099 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002100 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2101 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302102 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002103 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302104 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2105 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002106 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2107 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002108 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2109 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302110 return
mpagenkodff5dda2020-08-28 11:52:01 +00002111 }
2112 }
mpagenko01e726e2020-10-23 09:45:29 +00002113 */
mpagenkodff5dda2020-08-28 11:52:01 +00002114 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2115 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302116 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002117 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302118 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002119 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302120 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002121 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002122 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302123 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002124 }
2125 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2126 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302127 *loAddPcp = uint8(field.GetVlanPcp())
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 "PCP": loAddPcp})
2130 }
2131 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
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-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2135 }
2136 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
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 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2140 }
2141 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
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-DST": field.GetIpv4Dst()})
2145 }
2146 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
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 "IPv4-SRC": field.GetIpv4Src()})
2150 }
2151 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2152 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002154 "Metadata": field.GetTableMetadata()})
2155 }
2156 /*
2157 default:
2158 {
2159 //all other entires ignored
2160 }
2161 */
2162 }
2163 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302164}
mpagenkodff5dda2020-08-28 11:52:01 +00002165
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002167 for _, action := range flow.GetActions(apFlowItem) {
2168 switch action.Type {
2169 /* not used:
2170 case of.OfpActionType_OFPAT_OUTPUT:
2171 {
mpagenko01e726e2020-10-23 09:45:29 +00002172 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002173 "Output": action.GetOutput()})
2174 }
2175 */
2176 case of.OfpActionType_OFPAT_PUSH_VLAN:
2177 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002179 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2180 }
2181 case of.OfpActionType_OFPAT_SET_FIELD:
2182 {
2183 pActionSetField := action.GetSetField()
2184 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002186 "OxcmClass": pActionSetField.Field.OxmClass})
2187 }
2188 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302189 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302191 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002192 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302193 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302195 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002196 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002198 "Type": pActionSetField.Field.GetOfbField().Type})
2199 }
2200 }
2201 /*
2202 default:
2203 {
2204 //all other entires ignored
2205 }
2206 */
2207 }
2208 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302209}
2210
2211//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302213 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2214 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2215 var loAddPcp, loSetPcp uint8
2216 var loIPProto uint32
2217 /* the TechProfileId is part of the flow Metadata - compare also comment within
2218 * OLT-Adapter:openolt_flowmgr.go
2219 * Metadata 8 bytes:
2220 * Most Significant 2 Bytes = Inner VLAN
2221 * Next 2 Bytes = Tech Profile ID(TPID)
2222 * Least Significant 4 Bytes = Port ID
2223 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2224 * subscriber related flows.
2225 */
2226
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302228 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302230 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002231 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302232 }
mpagenko551a4d42020-12-08 18:09:20 +00002233 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002234 loCookie := apFlowItem.GetCookie()
2235 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002237 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302238
dbainbri4d3a0dc2020-12-02 00:33:42 +00002239 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002240 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302241 if loIPProto == 2 {
2242 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2243 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002244 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2245 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302246 return nil
2247 }
mpagenko01e726e2020-10-23 09:45:29 +00002248 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002250
2251 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002253 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2254 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2255 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2256 //TODO!!: Use DeviceId within the error response to rwCore
2257 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002258 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002259 }
2260 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002262 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2263 } else {
2264 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2265 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2266 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302267 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002268 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002270 }
mpagenko9a304ea2020-12-16 15:54:01 +00002271
2272 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2273 dh.lockVlanConfig.Lock()
2274 defer dh.lockVlanConfig.Unlock()
2275 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302276 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002277 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002278 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002279 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002281 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002282}
2283
2284//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002286 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2287 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2288 //no extra check is done on the rule parameters
2289 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2290 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2291 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2292 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002293 // - 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 +00002294 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002295 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002296
2297 /* TT related temporary workaround - should not be needed anymore
2298 for _, field := range flow.GetOfbFields(apFlowItem) {
2299 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2300 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002301 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002302 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2303 if loIPProto == 2 {
2304 // 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 +00002305 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002306 log.Fields{"device-id": dh.deviceID})
2307 return nil
2308 }
2309 }
2310 } //for all OfbFields
2311 */
2312
mpagenko9a304ea2020-12-16 15:54:01 +00002313 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2314 dh.lockVlanConfig.Lock()
2315 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002316 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002318 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002320 log.Fields{"device-id": dh.deviceID})
2321 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002322 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002324
mpagenko01e726e2020-10-23 09:45:29 +00002325 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002326}
2327
Himani Chawla26e555c2020-08-31 12:30:20 +05302328// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002329// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002330func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002331 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002332 chVlanFilterFsm := make(chan Message, 2048)
2333
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002335 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302337 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002338 }
2339
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002341 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2342 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002343 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302344 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002345 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2346 if pVlanFilterStatemachine != nil {
2347 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2348 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302350 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002351 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302352 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302354 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2355 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002356 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002357 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002358 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302359 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state 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 StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002363 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302364 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002365 }
2366 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002367 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002368 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002370 }
2371 return nil
2372}
2373
mpagenkofc4f56e2020-11-04 17:17:49 +00002374//VerifyVlanConfigRequest checks on existence of a given uniPort
2375// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002376func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002377 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2378 var pCurrentUniPort *onuUniPort
2379 for _, uniPort := range dh.uniEntityMap {
2380 // only if this port is validated for operState transfer
2381 if uniPort.uniID == uint8(aUniID) {
2382 pCurrentUniPort = uniPort
2383 break //found - end search loop
2384 }
2385 }
2386 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002388 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2389 return
2390 }
mpagenko551a4d42020-12-08 18:09:20 +00002391 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002392}
2393
mpagenkodff5dda2020-08-28 11:52:01 +00002394//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002395func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002396 //TODO!! verify and start pending flow configuration
2397 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2398 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302399 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002400 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2401 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2402 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002403 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2404 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2405 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2406 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2407 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2408 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2409 } else {
2410 /***** UniVlanConfigFsm continued */
2411 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2412 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2413 "UniPort": apUniPort.portNo})
2414 }
2415 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2416 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2417 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2418 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2419 } else {
2420 /***** UniVlanConfigFsm continued */
2421 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2422 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2423 "UniPort": apUniPort.portNo})
2424 }
mpagenkodff5dda2020-08-28 11:52:01 +00002425 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002426 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2427 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002428 "UniPort": apUniPort.portNo})
2429 }
2430 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002431 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2432 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2433 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002434 }
2435 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002437 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002438 }
mpagenkodff5dda2020-08-28 11:52:01 +00002439 } // else: nothing to do
2440}
2441
2442//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2443// 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 +00002444func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2445 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002446 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2447 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302448 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002449}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002450
Girish Gowdra26a40922021-01-29 17:14:34 -08002451//ProcessPendingTpDelete processes any pending TP delete (if available)
2452func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2453 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2454 if apUniPort == nil {
2455 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2456 return
2457 }
2458 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2459 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2460 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2461 if pAniConfigStatemachine != nil {
2462 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2463 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2464 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2465 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2466 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2467 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2468 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2469 return
2470 }
2471 } else {
2472 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2473 return
2474 }
2475 }
2476 return
2477 }
2478}
2479
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002480//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2481//available for potential reconcilement
2482
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002484
2485 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002486 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002487 return nil
2488 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002489 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002490
dbainbri4d3a0dc2020-12-02 00:33:42 +00002491 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002492 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002494 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2495 }
2496 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2497
2498 pDevEntry.lockOnuKVStoreMutex()
2499 defer pDevEntry.unlockOnuKVStoreMutex()
2500
2501 // deadline context to ensure completion of background routines waited for
2502 //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 +05302503 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002504 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2505
2506 pDevEntry.resetKvProcessingErrorIndication()
2507 var wg sync.WaitGroup
2508 wg.Add(1) // for the 1 go routine to finish
2509
dbainbri4d3a0dc2020-12-02 00:33:42 +00002510 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2511 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002512
2513 return pDevEntry.getKvProcessingErrorIndication()
2514}
2515
dbainbri4d3a0dc2020-12-02 00:33:42 +00002516func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002517 defer cancel() //ensure termination of context (may be pro forma)
2518 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002520 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002521}
2522
dbainbri4d3a0dc2020-12-02 00:33:42 +00002523func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002524
2525 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002527 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2529 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002530 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002531 return err
2532 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002533 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002534 return nil
2535 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002537 return nil
2538}
2539
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2541 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002542 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002543 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002544 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2545 }
2546 pDevEntry.lockOnuKVStoreMutex()
2547 defer pDevEntry.unlockOnuKVStoreMutex()
2548
2549 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2550 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2551
2552 pDevEntry.resetKvProcessingErrorIndication()
2553 var wg sync.WaitGroup
2554 wg.Add(1) // for the 1 go routine to finish
2555
2556 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002558
2559 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002560 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002561 return err
2562 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002563 return nil
2564}
2565
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002566func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2567 var errStr string = ""
2568 for _, err := range errS {
2569 if err != nil {
2570 errStr = errStr + err.Error() + " "
2571 }
2572 }
2573 if errStr != "" {
2574 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2575 }
2576 return nil
2577}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002578
2579// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2580func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2581 dh.lockDevice.RLock()
2582 defer dh.lockDevice.RUnlock()
2583 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2584 return uniPort.entityID, nil
2585 }
2586 return 0, errors.New("error-fetching-uni-port")
2587}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002588
2589// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002590func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2591 var errorsList []error
2592 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": dh.device.Id, "new-pm-configs": pmConfigs, "old-pm-config": dh.pmConfigs})
Girish Gowdrae09a6202021-01-12 18:10:59 -08002593
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002594 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2595 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2596 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2597
2598 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2599 // successfully.
2600 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2601 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2602 if len(errorsList) > 0 {
2603 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2604 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002605 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002606 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2607 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002608}
2609
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002610func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2611 var err error
2612 var errorsList []error
2613 logger.Infow(ctx, "handling-global-pm-config-params", log.Fields{"device-id": dh.device.Id})
2614
2615 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2616 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2617 errorsList = append(errorsList, err)
2618 }
2619 }
2620
2621 return errorsList
2622}
2623
2624func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2625 var err error
2626 var errorsList []error
2627 logger.Debugw(ctx, "handling-group-pm-config-params", log.Fields{"device-id": dh.device.Id})
2628 // Check if group metric related config is updated
2629 for _, v := range pmConfigs.Groups {
2630 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2631 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2632 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2633
2634 if ok && m.frequency != v.GroupFreq {
2635 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2636 errorsList = append(errorsList, err)
2637 }
2638 }
2639 if ok && m.enabled != v.Enabled {
2640 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2641 errorsList = append(errorsList, err)
2642 }
2643 }
2644 }
2645 return errorsList
2646}
2647
2648func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2649 var err error
2650 var errorsList []error
2651 logger.Debugw(ctx, "handling-individual-pm-config-params", log.Fields{"device-id": dh.device.Id})
2652 // Check if standalone metric related config is updated
2653 for _, v := range pmConfigs.Metrics {
2654 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002655 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002656 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2657
2658 if ok && m.frequency != v.SampleFreq {
2659 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2660 errorsList = append(errorsList, err)
2661 }
2662 }
2663 if ok && m.enabled != v.Enabled {
2664 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2665 errorsList = append(errorsList, err)
2666 }
2667 }
2668 }
2669 return errorsList
2670}
2671
2672// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002673func (dh *deviceHandler) startCollector(ctx context.Context) {
2674 logger.Debugf(ctx, "startingCollector")
2675
2676 // Start routine to process OMCI GET Responses
2677 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002678 // Initialize the next metric collection time.
2679 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2680 // reset like onu rebooted.
2681 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002682 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002683 for {
2684 select {
2685 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002686 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002687 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
2688 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2689 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002690 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2691 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2692 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2693 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2694 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002695 // Update the next metric collection time.
2696 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002697 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002698 } else {
2699 if dh.pmConfigs.Grouped { // metrics are managed as a group
2700 // parse through the group and standalone metrics to see it is time to collect their metrics
2701 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002702
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002703 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2704 // If the group is enabled AND (current time is equal to OR after nextCollectionInterval, collect the group metric)
2705 if g.enabled && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
2706 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2707 }
2708 }
2709 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2710 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2711 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2712 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2713 }
2714 }
2715 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2716
2717 // parse through the group and update the next metric collection time
2718 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2719 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2720 // If group enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2721 if g.enabled && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
2722 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2723 }
2724 }
2725 // parse through the standalone metrics and update the next metric collection time
2726 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2727 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2728 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2729 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2730 }
2731 }
2732 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2733 } /* else { // metrics are not managed as a group
2734 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2735 } */
2736 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002737 }
2738 }
2739}
kesavandfdf77632021-01-26 23:40:33 -05002740
2741func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2742
2743 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2744 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2745}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002746
2747func (dh *deviceHandler) isFsmInState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2748 var currentState string
2749 if pFsm != nil {
2750 currentState = pFsm.Current()
2751 if currentState == wantedState {
2752 return true
2753 }
2754 } else {
2755 logger.Warnw(ctx, "FSM not defined!", log.Fields{"wantedState": wantedState, "device-id": dh.deviceID})
2756 }
2757 return false
2758}
2759
2760func (dh *deviceHandler) mibUploadFsmInIdleState(ctx context.Context, idleState string) bool {
2761 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibUploadFsm.pFsm, idleState)
2762}
2763
2764func (dh *deviceHandler) mibDownloadFsmInIdleState(ctx context.Context, idleState string) bool {
2765 return dh.isFsmInState(ctx, dh.pOnuOmciDevice.pMibDownloadFsm.pFsm, idleState)
2766}
2767
2768func (dh *deviceHandler) devUniLockFsmInIdleState(ctx context.Context, idleState string) bool {
2769 return dh.isFsmInState(ctx, dh.pLockStateFsm.pAdaptFsm.pFsm, idleState)
2770}
2771
2772func (dh *deviceHandler) devUniUnlockFsmInIdleState(ctx context.Context, idleState string) bool {
2773 return dh.isFsmInState(ctx, dh.pUnlockStateFsm.pAdaptFsm.pFsm, idleState)
2774}
2775
2776func (dh *deviceHandler) devAniConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2777 if dh.pOnuTP.pAniConfigFsm != nil {
2778 for _, v := range dh.pOnuTP.pAniConfigFsm {
2779 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2780 return false
2781 }
2782 }
2783 return true
2784 }
2785 logger.Warnw(ctx, "AniConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2786 return false
2787}
2788
2789func (dh *deviceHandler) devUniVlanConfigFsmInIdleState(ctx context.Context, idleState string) bool {
2790 if dh.UniVlanConfigFsmMap != nil {
2791 for _, v := range dh.UniVlanConfigFsmMap {
2792 if !dh.isFsmInState(ctx, v.pAdaptFsm.pFsm, idleState) {
2793 return false
2794 }
2795 }
2796 return true
2797 }
2798 logger.Warnw(ctx, "UniVlanConfig FSM not defined!", log.Fields{"device-id": dh.deviceID})
2799 return false
2800}
2801
2802func (dh *deviceHandler) allButCallingFsmInIdleState(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
2803 for fsmName, fsmStruct := range fsmIdleStateFuncMap {
2804 if fsmName != callingFsm && !fsmStruct.idleCheckFunc(dh, ctx, fsmStruct.idleState) {
2805 return false
2806 }
2807 }
2808 return true
2809}
2810
2811func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
2812 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
2813 if err := dh.resetFsms(ctx, false); err != nil {
2814 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
2815 // TODO: fatal error reset ONU, delete deviceHandler!
2816 return
2817 }
2818 if !dh.getCollectorIsRunning() {
2819 // Start PM collector routine
2820 go dh.startCollector(ctx)
2821 }
2822 dh.uniEntityMap = make(map[uint32]*onuUniPort)
2823 dh.reconciling = true
2824}
2825
2826func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
2827 dh.mutexCollectorFlag.Lock()
2828 dh.collectorIsRunning = flagValue
2829 dh.mutexCollectorFlag.Unlock()
2830}
2831
2832func (dh *deviceHandler) getCollectorIsRunning() bool {
2833 dh.mutexCollectorFlag.RLock()
2834 flagValue := dh.collectorIsRunning
2835 dh.mutexCollectorFlag.RUnlock()
2836 return flagValue
2837}