blob: 0e0c1afdbf5467e465fcb5dc7f08fa8ce963ba47 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/hex"
23 "errors"
24 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
34 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053035 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000036 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v4/pkg/log"
38 vc "github.com/opencord/voltha-protos/v4/go/common"
39 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt80129db2020-11-23 10:49:32 +000094const (
95 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +000096 drUnset = 0
97 drActivatingOnu = 1
98 drStartingOpenomci = 2
99 drDiscoveryMibsyncComplete = 3
100 drInitialMibDownloaded = 4
101 drTechProfileConfigDownloadSuccess = 5
102 drOmciFlowsPushed = 6
103 drOmciAdminLock = 7
104 drOnuReenabled = 8
105 drStoppingOpenomci = 9
106 drRebooting = 10
107 drOmciFlowsDeleted = 11
108 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000109)
110
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000111var deviceReasonMap = map[uint8]string{
112 drUnset: "unset",
113 drActivatingOnu: "activating-onu",
114 drStartingOpenomci: "starting-openomci",
115 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
116 drInitialMibDownloaded: "initial-mib-downloaded",
117 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
118 drOmciFlowsPushed: "omci-flows-pushed",
119 drOmciAdminLock: "omci-admin-lock",
120 drOnuReenabled: "onu-reenabled",
121 drStoppingOpenomci: "stopping-openomci",
122 drRebooting: "rebooting",
123 drOmciFlowsDeleted: "omci-flows-deleted",
124 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
125}
126
Himani Chawla6d2ae152020-09-02 13:11:20 +0530127//deviceHandler will interact with the ONU ? device.
128type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000129 deviceID string
130 DeviceType string
131 adminState string
132 device *voltha.Device
133 logicalDeviceID string
134 ProxyAddressID string
135 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530136 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000137 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000138
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000139 coreProxy adapterif.CoreProxy
140 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530141 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000142
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000143 pOpenOnuAc *OpenONUAC
144 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530145 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000146 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000147 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530148 pOnuTP *onuUniTechProf
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000149 exitChannel chan int
150 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000151 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000152 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153 pLockStateFsm *lockStateFsm
154 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000156 //flowMgr *OpenOltFlowMgr
157 //eventMgr *OpenOltEventMgr
158 //resourceMgr *rsrcMgr.OpenOltResourceMgr
159
160 //discOnus sync.Map
161 //onus sync.Map
162 //portStats *OpenOltStatisticsMgr
163 //metrics *pmmetrics.PmMetrics
mpagenkofc4f56e2020-11-04 17:17:49 +0000164 stopCollector chan bool
165 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000166 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000167 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000168 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
169 reconciling bool
170 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171}
172
Himani Chawla6d2ae152020-09-02 13:11:20 +0530173//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530174func 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 +0530175 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000176 dh.coreProxy = cp
177 dh.AdapterProxy = ap
178 dh.EventProxy = ep
179 cloned := (proto.Clone(device)).(*voltha.Device)
180 dh.deviceID = cloned.Id
181 dh.DeviceType = cloned.Type
182 dh.adminState = "up"
183 dh.device = cloned
184 dh.pOpenOnuAc = adapter
185 dh.exitChannel = make(chan int, 1)
186 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000187 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000188 dh.stopCollector = make(chan bool, 2)
189 dh.stopHeartbeatCheck = make(chan bool, 2)
190 //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 +0000191 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530192 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000193 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000194 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000195 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000196 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197
198 // Device related state machine
199 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000200 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000202 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
203 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
204 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
205 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
206 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000207 },
208 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000209 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
210 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
211 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
212 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
213 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
214 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
215 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
216 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000217 },
218 )
mpagenkoaf801632020-07-03 10:00:42 +0000219
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220 return &dh
221}
222
Himani Chawla6d2ae152020-09-02 13:11:20 +0530223// start save the device to the data model
224func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000225 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000226 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228}
229
Himani Chawla4d908332020-08-31 12:30:20 +0530230/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000231// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 logger.Debug("stopping-device-handler")
234 dh.exitChannel <- 1
235}
Himani Chawla4d908332020-08-31 12:30:20 +0530236*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237
238// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530239// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241//adoptOrReconcileDevice adopts the OLT device
242func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000243 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244
dbainbri4d3a0dc2020-12-02 00:33:42 +0000245 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000246 if dh.pDeviceStateFsm.Is(devStNull) {
247 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000248 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000250 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000252 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000253 }
254
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255}
256
dbainbri4d3a0dc2020-12-02 00:33:42 +0000257func (dh *deviceHandler) processInterAdapterOMCIReqMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530258 msgBody := msg.GetBody()
259 omciMsg := &ic.InterAdapterOmciMessage{}
260 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000261 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530262 "device-id": dh.deviceID, "error": err})
263 return err
264 }
265
266 //assuming omci message content is hex coded!
267 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000268 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530269 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
270 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000271 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530272 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000273 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000274 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000275 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000276 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 +0530277 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000279 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530280}
281
Himani Chawla6d2ae152020-09-02 13:11:20 +0530282func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000283 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530284 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000285
dbainbri4d3a0dc2020-12-02 00:33:42 +0000286 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000287
dbainbri4d3a0dc2020-12-02 00:33:42 +0000288 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000289 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000291 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
292 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530293 if dh.pOnuTP == nil {
294 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000295 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530296 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000297 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530298 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000299 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000301 "device-state": deviceReasonMap[dh.deviceReason]})
302 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530303 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000304 //previous state test here was just this one, now extended for more states to reject the SetRequest:
305 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
306 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530307
308 msgBody := msg.GetBody()
309 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
310 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530312 "device-id": dh.deviceID, "error": err})
313 return err
314 }
315
316 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000317 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
318 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530319 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000320 defer dh.pOnuTP.unlockTpProcMutex()
321 pDevEntry.lockOnuKVStoreMutex()
322 defer pDevEntry.unlockOnuKVStoreMutex()
323
324 if techProfMsg.UniId > 255 {
325 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
326 techProfMsg.UniId, dh.deviceID))
327 }
328 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800329 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
330 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800332 return err
333 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000334
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 // if there has been some change for some uni TechProfilePath
337 //in order to allow concurrent calls to other dh instances we do not wait for execution here
338 //but doing so we can not indicate problems to the caller (who does what with that then?)
339 //by now we just assume straightforward successful execution
340 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
341 // possible problems to the caller later autonomously
342
343 // deadline context to ensure completion of background routines waited for
344 //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 +0530345 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 dctx, cancel := context.WithDeadline(context.Background(), deadline)
347
Girish Gowdra041dcb32020-11-16 16:54:30 -0800348 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000349 pDevEntry.resetKvProcessingErrorIndication()
350
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 var wg sync.WaitGroup
352 wg.Add(2) // for the 2 go routines to finish
353 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
355 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
356 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000357
Girish Gowdra041dcb32020-11-16 16:54:30 -0800358 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000360 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 return nil
362}
363
Himani Chawla6d2ae152020-09-02 13:11:20 +0530364func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 msg *ic.InterAdapterMessage) error {
367
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000369
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000371 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000372 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000373 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
374 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 if dh.pOnuTP == nil {
376 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530378 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 }
381
382 msgBody := msg.GetBody()
383 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
384 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000385 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 "device-id": dh.deviceID, "error": err})
387 return err
388 }
389
390 //compare TECH_PROFILE_DOWNLOAD_REQUEST
391 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 defer dh.pOnuTP.unlockTpProcMutex()
393 pDevEntry.lockOnuKVStoreMutex()
394 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530395
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 if delGemPortMsg.UniId > 255 {
397 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
398 delGemPortMsg.UniId, dh.deviceID))
399 }
400 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800401 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
402 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000403 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 -0800404 return err
405 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530406
mpagenkofc4f56e2020-11-04 17:17:49 +0000407 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408
mpagenkofc4f56e2020-11-04 17:17:49 +0000409 // deadline context to ensure completion of background routines waited for
410 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
411 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412
Girish Gowdra041dcb32020-11-16 16:54:30 -0800413 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000414
mpagenkofc4f56e2020-11-04 17:17:49 +0000415 var wg sync.WaitGroup
416 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000417 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000418 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000419 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000420
Girish Gowdra041dcb32020-11-16 16:54:30 -0800421 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530422}
423
Himani Chawla6d2ae152020-09-02 13:11:20 +0530424func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000425 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530426 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000427
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000429
dbainbri4d3a0dc2020-12-02 00:33:42 +0000430 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000431 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000433 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
434 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 if dh.pOnuTP == nil {
436 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000437 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530438 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000439 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 }
441
442 msgBody := msg.GetBody()
443 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
444 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000445 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 "device-id": dh.deviceID, "error": err})
447 return err
448 }
449
450 //compare TECH_PROFILE_DOWNLOAD_REQUEST
451 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452 defer dh.pOnuTP.unlockTpProcMutex()
453 pDevEntry.lockOnuKVStoreMutex()
454 defer pDevEntry.unlockOnuKVStoreMutex()
455
456 if delTcontMsg.UniId > 255 {
457 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
458 delTcontMsg.UniId, dh.deviceID))
459 }
460 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800461 tpPath := delTcontMsg.TpPath
462 tpID, err := GetTpIDFromTpPath(tpPath)
463 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000464 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800465 return err
466 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467
dbainbri4d3a0dc2020-12-02 00:33:42 +0000468 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530470 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530471 dctx, cancel := context.WithDeadline(context.Background(), deadline)
472
Girish Gowdra041dcb32020-11-16 16:54:30 -0800473 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000474 pDevEntry.resetKvProcessingErrorIndication()
475
Himani Chawla26e555c2020-08-31 12:30:20 +0530476 var wg sync.WaitGroup
477 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 cResourceTcont, delTcontMsg.AllocId, &wg)
480 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
482 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483
Girish Gowdra041dcb32020-11-16 16:54:30 -0800484 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 return nil
487}
488
Himani Chawla6d2ae152020-09-02 13:11:20 +0530489//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000490// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
491// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000493 msgID := msg.Header.Id
494 msgType := msg.Header.Type
495 fromTopic := msg.Header.FromTopic
496 toTopic := msg.Header.ToTopic
497 toDeviceID := msg.Header.ToDeviceId
498 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000500 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
501
502 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000503 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000504 case ic.InterAdapterMessageType_OMCI_REQUEST:
505 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 return dh.processInterAdapterOMCIReqMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000507 }
mpagenkoaf801632020-07-03 10:00:42 +0000508 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
509 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000511 }
512 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
513 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000515
mpagenkoaf801632020-07-03 10:00:42 +0000516 }
517 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
518 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000520 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000521 default:
522 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 "msgType": msg.Header.Type, "device-id": dh.deviceID})
525 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000526 }
527 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000528}
529
mpagenkodff5dda2020-08-28 11:52:01 +0000530//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
532 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000533 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000535
mpagenko01e726e2020-10-23 09:45:29 +0000536 var retError error = nil
537 //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 +0000538 if apOfFlowChanges.ToRemove != nil {
539 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000540 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000541 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000542 "device-id": dh.deviceID})
543 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000544 continue
545 }
546 flowInPort := flow.GetInPort(flowItem)
547 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548 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 +0000549 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
550 continue
551 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000552 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000553 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000554 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000555 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000556 continue
557 } else {
558 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530559 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000560 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
561 loUniPort = uniPort
562 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000564 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
565 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
566 flowInPort, dh.deviceID)
567 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000568 }
569 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000571 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000572 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000573 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000574 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000575 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000577 log.Fields{"device-id": dh.deviceID, "error": err})
578 retError = err
579 continue
580 //return err
581 } else { // if last setting succeeds, overwrite possibly previously set error
582 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000583 }
584 }
585 }
586 }
mpagenko01e726e2020-10-23 09:45:29 +0000587 if apOfFlowChanges.ToAdd != nil {
588 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
589 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000591 "device-id": dh.deviceID})
592 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
593 continue
594 }
595 flowInPort := flow.GetInPort(flowItem)
596 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 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 +0000598 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
599 continue
600 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
601 } else if flowInPort == dh.ponPortNumber {
602 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000604 "device-id": dh.deviceID, "inPort": flowInPort})
605 continue
606 } else {
607 // this is the relevant upstream flow
608 var loUniPort *onuUniPort
609 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
610 loUniPort = uniPort
611 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000613 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
614 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
615 flowInPort, dh.deviceID)
616 continue
617 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
618 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000619 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
620 // if not, we just throw some error here to have an indication about that, if we really need to support that
621 // then we would need to create some means to activate the internal stored flows
622 // after the device gets active automatically (and still with its dependency to the TechProfile)
623 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
624 // also abort for the other still possible flows here
625 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000627 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000628 return fmt.Errorf("improper device state on device %s", dh.deviceID)
629 }
630
mpagenko01e726e2020-10-23 09:45:29 +0000631 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000633 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
634 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000635 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000636 //try next flow after processing error
637 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000639 log.Fields{"device-id": dh.deviceID, "error": err})
640 retError = err
641 continue
642 //return err
643 } else { // if last setting succeeds, overwrite possibly previously set error
644 retError = nil
645 }
646 }
647 }
648 }
649 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000650}
651
Himani Chawla6d2ae152020-09-02 13:11:20 +0530652//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000653//following are the expected device states after this activity:
654//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
655// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
657 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000658
mpagenko900ee4b2020-10-12 11:56:34 +0000659 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000660 //note that disableDevice sequences in some 'ONU active' state may yield also
661 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000662 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000663 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000664 //disable-device shall be just a UNi/ONU-G related admin state setting
665 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000666
mpagenkofc4f56e2020-11-04 17:17:49 +0000667 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000668 // disable UNI ports/ONU
669 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
670 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000672 } else { //LockStateFSM already init
673 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000675 }
676 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000678 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000680 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
681 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000683 }
mpagenko01e726e2020-10-23 09:45:29 +0000684 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000685
686 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000688 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300689 }
690}
691
Himani Chawla6d2ae152020-09-02 13:11:20 +0530692//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
694 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000695
mpagenkofc4f56e2020-11-04 17:17:49 +0000696 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
697 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
698 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
699 // for real ONU's that should have nearly no influence
700 // Note that for real ONU's there is anyway a problematic situation with following sequence:
701 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
702 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
703 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
704 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
705
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000706 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000707 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000708 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000710 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000711 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000713 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300714}
715
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
717 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000718
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000720 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000722 return
723 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000725 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000727 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000729 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000730 dh.reconciling = false
731 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000732 }
Himani Chawla4d908332020-08-31 12:30:20 +0530733 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000734 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
735 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
736 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
737 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000739}
740
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
742 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000743
dbainbri4d3a0dc2020-12-02 00:33:42 +0000744 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000745 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000746 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000747 return
748 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000749 dh.pOnuTP.lockTpProcMutex()
750 defer dh.pOnuTP.unlockTpProcMutex()
751
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000752 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000754 log.Fields{"device-id": dh.deviceID})
755 dh.reconciling = false
756 return
757 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000758 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000759 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
760 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000762 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
763 dh.reconciling = false
764 return
765 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800766 for tpID := range uniData.PersTpPathMap {
767 // deadline context to ensure completion of background routines waited for
768 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
769 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000771
Girish Gowdra041dcb32020-11-16 16:54:30 -0800772 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
773 var wg sync.WaitGroup
774 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
776 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800777 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800779 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000780 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000781 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000783 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
784 dh.reconciling = false
785 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000786 }
787}
788
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
790 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000791
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000793 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000795 return
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.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Debugw(ctx, "reconciling - no flows 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 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000811 var uniPort *onuUniPort
812 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000814 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 return
817 }
818 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000820 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000821 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000823 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
824 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000828 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000829 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000830 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000831 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 }
833 }
834 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000837 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
838 dh.reconciling = false
839 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000840 }
841}
842
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
844 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 +0000845
846 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000847 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000848}
849
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
851 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000854 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000855 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000857 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000858 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 pDevEntry.lockOnuKVStoreMutex()
860 defer pDevEntry.unlockOnuKVStoreMutex()
861
862 // deadline context to ensure completion of background routines waited for
863 //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 +0530864 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866
867 pDevEntry.resetKvProcessingErrorIndication()
868
869 var wg sync.WaitGroup
870 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
872 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000873
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000874 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000876}
877
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
879 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300880 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300883 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000884 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530885 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530887 return err
888 }
mpagenko01e726e2020-10-23 09:45:29 +0000889
890 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000892
dbainbri4d3a0dc2020-12-02 00:33:42 +0000893 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000894 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300896 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000897 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300899 return err
900 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300902 return err
903 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000904 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000905 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
906 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
907 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
908 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300909 return nil
910}
911
mpagenkoc8bba412021-01-15 15:38:44 +0000912//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
913func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
914 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
915 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
916 return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
917}
918
Himani Chawla6d2ae152020-09-02 13:11:20 +0530919// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000920// #####################################################################################
921
922// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530923// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000924
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
926 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 +0000927}
928
929// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000931
dbainbri4d3a0dc2020-12-02 00:33:42 +0000932 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000933 var err error
934
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000935 // populate what we know. rest comes later after mib sync
936 dh.device.Root = false
937 dh.device.Vendor = "OpenONU"
938 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000939 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000940 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000941
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000942 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000943
944 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
946 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530947 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000948 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000950 log.Fields{"device-id": dh.deviceID})
951 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000952
Himani Chawla4d908332020-08-31 12:30:20 +0530953 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000954 dh.ponPortNumber = dh.device.ParentPortNo
955
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000956 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
957 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
958 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000960 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530961 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000962
963 /*
964 self._pon = PonPort.create(self, self._pon_port_number)
965 self._pon.add_peer(self.parent_id, self._pon_port_number)
966 self.logger.debug('adding-pon-port-to-agent',
967 type=self._pon.get_port().type,
968 admin_state=self._pon.get_port().admin_state,
969 oper_status=self._pon.get_port().oper_status,
970 )
971 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000972 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000973 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000974 var ponPortNo uint32 = 1
975 if dh.ponPortNumber != 0 {
976 ponPortNo = dh.ponPortNumber
977 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000978
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000979 pPonPort := &voltha.Port{
980 PortNo: ponPortNo,
981 Label: fmt.Sprintf("pon-%d", ponPortNo),
982 Type: voltha.Port_PON_ONU,
983 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530984 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000985 PortNo: ponPortNo}}, // Peer port is parent's port number
986 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000987 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
988 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000989 e.Cancel(err)
990 return
991 }
992 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000994 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000996}
997
998// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001000
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001002 var err error
1003 /*
1004 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1005 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1006 return nil
1007 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1009 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001010 e.Cancel(err)
1011 return
1012 }
1013
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001014 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001016 // reconcilement will be continued after mib download is done
1017 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001018 /*
1019 ############################################################################
1020 # Setup Alarm handler
1021 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1022 device.serial_number)
1023 ############################################################################
1024 # Setup PM configuration for this device
1025 # Pass in ONU specific options
1026 kwargs = {
1027 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1028 'heartbeat': self.heartbeat,
1029 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1030 }
1031 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1032 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1033 self.logical_device_id, device.serial_number,
1034 grouped=True, freq_override=False, **kwargs)
1035 pm_config = self._pm_metrics.make_proto()
1036 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1037 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1038 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1039
1040 # Note, ONU ID and UNI intf set in add_uni_port method
1041 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1042 ani_ports=[self._pon])
1043
1044 # Code to Run OMCI Test Action
1045 kwargs_omci_test_action = {
1046 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1047 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1048 }
1049 serial_number = device.serial_number
1050 self._test_request = OmciTestRequest(self.core_proxy,
1051 self.omci_agent, self.device_id,
1052 AniG, serial_number,
1053 self.logical_device_id,
1054 exclusive=False,
1055 **kwargs_omci_test_action)
1056
1057 self.enabled = True
1058 else:
1059 self.logger.info('onu-already-activated')
1060 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001062}
1063
1064// doStateConnected get the device info and update to voltha core
1065// for comparison of the original method (not that easy to uncomment): compare here:
1066// voltha-openolt-adapter/adaptercore/device_handler.go
1067// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001068func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301071 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001072 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074}
1075
1076// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001077func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001078
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301080 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001081 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001082 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001083
1084 /*
1085 // Synchronous call to update device state - this method is run in its own go routine
1086 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1087 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001088 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 +00001089 return err
1090 }
1091 return nil
1092 */
1093}
1094
1095// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001096func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001097
dbainbri4d3a0dc2020-12-02 00:33:42 +00001098 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001099 var err error
1100
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001101 device := dh.device
1102 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001103 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001105 e.Cancel(err)
1106 return
1107 }
1108
1109 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001111 /*
1112 // Update the all ports state on that device to disable
1113 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001114 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115 return er
1116 }
1117
1118 //Update the device oper state and connection status
1119 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1120 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1121 dh.device = cloned
1122
1123 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001124 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125 return er
1126 }
1127
1128 //get the child device for the parent device
1129 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1130 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001131 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132 return err
1133 }
1134 for _, onuDevice := range onuDevices.Items {
1135
1136 // Update onu state as down in onu adapter
1137 onuInd := oop.OnuIndication{}
1138 onuInd.OperState = "down"
1139 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1140 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1141 if er != nil {
1142 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001143 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 //Do not return here and continue to process other ONUs
1145 }
1146 }
1147 // * Discovered ONUs entries need to be cleared , since after OLT
1148 // is up, it starts sending discovery indications again* /
1149 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001150 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001151 return nil
1152 */
Himani Chawla4d908332020-08-31 12:30:20 +05301153 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001154 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001156}
1157
Himani Chawla6d2ae152020-09-02 13:11:20 +05301158// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001159// #################################################################################
1160
1161// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301162// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001163
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001164//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001166 dh.lockDevice.RLock()
1167 pOnuDeviceEntry := dh.pOnuOmciDevice
1168 if aWait && pOnuDeviceEntry == nil {
1169 //keep the read sema short to allow for subsequent write
1170 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001171 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001172 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1173 // so it might be needed to wait here for that event with some timeout
1174 select {
1175 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001177 return nil
1178 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001179 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001180 // if written now, we can return the written value without sema
1181 return dh.pOnuOmciDevice
1182 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183 }
mpagenko3af1f032020-06-10 08:53:41 +00001184 dh.lockDevice.RUnlock()
1185 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001186}
1187
Himani Chawla6d2ae152020-09-02 13:11:20 +05301188//setOnuDeviceEntry sets the ONU device entry within the handler
1189func (dh *deviceHandler) setOnuDeviceEntry(
1190 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001191 dh.lockDevice.Lock()
1192 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001193 dh.pOnuOmciDevice = apDeviceEntry
1194 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001195}
1196
Himani Chawla6d2ae152020-09-02 13:11:20 +05301197//addOnuDeviceEntry creates a new ONU device or returns the existing
1198func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001199 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001200
dbainbri4d3a0dc2020-12-02 00:33:42 +00001201 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001202 if deviceEntry == nil {
1203 /* costum_me_map in python code seems always to be None,
1204 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1205 /* also no 'clock' argument - usage open ...*/
1206 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001207 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001208 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001209 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301210 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001211 // fire deviceEntry ready event to spread to possibly waiting processing
1212 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001213 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001214 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001215 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001216 }
1217 // might be updated with some error handling !!!
1218 return nil
1219}
1220
dbainbri4d3a0dc2020-12-02 00:33:42 +00001221func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1222 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001223 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1224
1225 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001226
dbainbri4d3a0dc2020-12-02 00:33:42 +00001227 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001228 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001230 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1231 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001232 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001233 if err := dh.storePersistentData(ctx); err != nil {
1234 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001235 log.Fields{"device-id": dh.deviceID, "err": err})
1236 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001238 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001239 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001240 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1241 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001243 }
1244 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001245 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001246 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001247
1248 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 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 +00001250 log.Fields{"device-id": dh.deviceID})
1251 dh.reconciling = false
1252 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001253 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001254 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1255 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1256 // 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 +00001257 // 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 +00001258 // so let's just try to keep it simple ...
1259 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001261 if err != nil || device == nil {
1262 //TODO: needs to handle error scenarios
1263 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1264 return errors.New("Voltha Device not found")
1265 }
1266 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001269 return err
mpagenko3af1f032020-06-10 08:53:41 +00001270 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001271
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001273
1274 /* this might be a good time for Omci Verify message? */
1275 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001277 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001278 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001280
1281 /* give the handler some time here to wait for the OMCi verification result
1282 after Timeout start and try MibUpload FSM anyway
1283 (to prevent stopping on just not supported OMCI verification from ONU) */
1284 select {
1285 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001287 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001288 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001289 }
1290
1291 /* In py code it looks earlier (on activate ..)
1292 # Code to Run OMCI Test Action
1293 kwargs_omci_test_action = {
1294 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1295 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1296 }
1297 serial_number = device.serial_number
1298 self._test_request = OmciTestRequest(self.core_proxy,
1299 self.omci_agent, self.device_id,
1300 AniG, serial_number,
1301 self.logical_device_id,
1302 exclusive=False,
1303 **kwargs_omci_test_action)
1304 ...
1305 # Start test requests after a brief pause
1306 if not self._test_request_started:
1307 self._test_request_started = True
1308 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1309 reactor.callLater(tststart, self._test_request.start_collector)
1310
1311 */
1312 /* which is then: in omci_test_request.py : */
1313 /*
1314 def start_collector(self, callback=None):
1315 """
1316 Start the collection loop for an adapter if the frequency > 0
1317
1318 :param callback: (callable) Function to call to collect PM data
1319 """
1320 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1321 if callback is None:
1322 callback = self.perform_test_omci
1323
1324 if self.lc is None:
1325 self.lc = LoopingCall(callback)
1326
1327 if self.default_freq > 0:
1328 self.lc.start(interval=self.default_freq / 10)
1329
1330 def perform_test_omci(self):
1331 """
1332 Perform the initial test request
1333 """
1334 ani_g_entities = self._device.configuration.ani_g_entities
1335 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1336 is not None else None
1337 self._entity_id = ani_g_entities_ids[0]
1338 self.logger.info('perform-test', entity_class=self._entity_class,
1339 entity_id=self._entity_id)
1340 try:
1341 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1342 result = yield self._device.omci_cc.send(frame)
1343 if not result.fields['omci_message'].fields['success_code']:
1344 self.logger.info('Self-Test Submitted Successfully',
1345 code=result.fields[
1346 'omci_message'].fields['success_code'])
1347 else:
1348 raise TestFailure('Test Failure: {}'.format(
1349 result.fields['omci_message'].fields['success_code']))
1350 except TimeoutError as e:
1351 self.deferred.errback(failure.Failure(e))
1352
1353 except Exception as e:
1354 self.logger.exception('perform-test-Error', e=e,
1355 class_id=self._entity_class,
1356 entity_id=self._entity_id)
1357 self.deferred.errback(failure.Failure(e))
1358
1359 */
1360
1361 // PM related heartbeat??? !!!TODO....
1362 //self._heartbeat.enabled = True
1363
mpagenko1cc3cb42020-07-27 15:24:38 +00001364 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1365 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1366 * 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 +05301367 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001368 */
1369 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001370 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001371 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001372 if pMibUlFsm.Is(ulStDisabled) {
1373 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001374 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 +00001375 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301376 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001377 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301378 //Determine ONU status and start/re-start MIB Synchronization tasks
1379 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001380 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301381 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001382 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 +00001383 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001384 }
Himani Chawla4d908332020-08-31 12:30:20 +05301385 } else {
1386 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001387 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 +00001388 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301389 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001390 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001391 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001392 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001394 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001395 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001396 }
1397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001398 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001399 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001400 }
1401 return nil
1402}
1403
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001405 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001406 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001407 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001408 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001409
mpagenko900ee4b2020-10-12 11:56:34 +00001410 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1411 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1412 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 if err := dh.resetFsms(ctx); err != nil {
1414 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001415 log.Fields{"device-id": dh.deviceID, "error": err})
1416 // abort: system behavior is just unstable ...
1417 return err
1418 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001419 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 _ = 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 +00001421
1422 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1423 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1424 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001426 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001427 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001428 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001429 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001431
1432 //TODO!!! remove existing traffic profiles
1433 /* from py code, if TP's exist, remove them - not yet implemented
1434 self._tp = dict()
1435 # Let TP download happen again
1436 for uni_id in self._tp_service_specific_task:
1437 self._tp_service_specific_task[uni_id].clear()
1438 for uni_id in self._tech_profile_download_done:
1439 self._tech_profile_download_done[uni_id].clear()
1440 */
1441
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001443
mpagenkofc4f56e2020-11-04 17:17:49 +00001444 dh.ReadyForSpecificOmciConfig = false
1445
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001447 // abort: system behavior is just unstable ...
1448 return err
1449 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001450 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001451 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001452 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001453 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001454 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001456 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001457 // abort: system behavior is just unstable ...
1458 return err
1459 }
1460 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001461 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001462 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001463 return nil
1464}
1465
dbainbri4d3a0dc2020-12-02 00:33:42 +00001466func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001467 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1468 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1469 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1470 // and using the stop/reset event should never harm
1471
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001473 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001474 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001475 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1476 }
mpagenko900ee4b2020-10-12 11:56:34 +00001477 //the MibSync FSM might be active all the ONU-active time,
1478 // hence it must be stopped unconditionally
1479 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1480 if pMibUlFsm != nil {
1481 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1482 }
1483 //MibDownload may run
1484 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1485 if pMibDlFsm != nil {
1486 _ = pMibDlFsm.Event(dlEvReset)
1487 }
1488 //port lock/unlock FSM's may be active
1489 if dh.pUnlockStateFsm != nil {
1490 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1491 }
1492 if dh.pLockStateFsm != nil {
1493 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1494 }
1495 //techProfile related PonAniConfigFsm FSM may be active
1496 if dh.pOnuTP != nil {
1497 // should always be the case here
1498 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1499 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001500 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1501 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1502 }
mpagenko900ee4b2020-10-12 11:56:34 +00001503 }
1504 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001505 // reset the possibly existing VlanConfigFsm
1506 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1507 //VlanFilterFsm exists and was already started
1508 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1509 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001510 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001511 // no need to remove specific data
1512 pVlanFilterFsm.RequestClearPersistency(false)
1513 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001514 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1515 }
1516 }
1517 }
1518 }
1519 //TODO!!! care about PM/Alarm processing once started
1520 return nil
1521}
1522
dbainbri4d3a0dc2020-12-02 00:33:42 +00001523func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1524 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 +05301525
dbainbri4d3a0dc2020-12-02 00:33:42 +00001526 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1527 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001528 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001530 return
1531 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001532 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001533 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1534 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1535 for _, mgmtEntityID := range pptpInstKeys {
1536 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1537 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001538 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301539 i++
1540 }
1541 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301543 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001544 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1545 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301546 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001547 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301548 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301550 i++
1551 }
1552 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301554 }
1555 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301557 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001558 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1559 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1560 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1561 * disable/enable toggling here to allow traffic
1562 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1563 * like the py comment says:
1564 * # start by locking all the unis till mib sync and initial mib is downloaded
1565 * # this way we can capture the port down/up events when we are ready
1566 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301567
mpagenkoa40e99a2020-11-17 13:50:39 +00001568 // Init Uni Ports to Admin locked state
1569 // *** should generate UniLockStateDone event *****
1570 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001572 } else { //LockStateFSM already init
1573 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001574 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001575 }
1576}
1577
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1579 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301580 /* Mib download procedure -
1581 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1582 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001584 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001586 return
1587 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301588 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1589 if pMibDlFsm != nil {
1590 if pMibDlFsm.Is(dlStDisabled) {
1591 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 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 +05301593 // maybe try a FSM reset and then again ... - TODO!!!
1594 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001595 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301596 // maybe use more specific states here for the specific download steps ...
1597 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301599 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301601 //Begin MIB data download (running autonomously)
1602 }
1603 }
1604 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001606 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301607 // maybe try a FSM reset and then again ... - TODO!!!
1608 }
1609 /***** Mib download started */
1610 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301612 }
1613}
1614
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1616 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301617 //initiate DevStateUpdate
1618 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001620 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301622 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1623 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301625 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301627 }
1628 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001630 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001632 return
1633 }
1634 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 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 +00001636 log.Fields{"device-id": dh.deviceID})
1637 dh.reconciling = false
1638 return
1639 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301641 log.Fields{"device-id": dh.deviceID})
1642 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001644 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301645 // *** should generate UniUnlockStateDone event *****
1646 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301648 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301649 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301651 }
1652}
1653
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1655 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301656
1657 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001658 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301659 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1661 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001662 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001664 return
1665 }
1666 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 if err := dh.storePersistentData(ctx); err != nil {
1668 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001669 log.Fields{"device-id": dh.deviceID, "err": err})
1670 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301671 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672 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 +05301673 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001675 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 }
1677}
1678
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1680 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001681 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001683 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1684 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001686 }
1687
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001689 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001691
1692 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001696 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001698 return
1699 }
1700 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701 if err := dh.storePersistentData(ctx); err != nil {
1702 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001703 log.Fields{"device-id": dh.deviceID, "err": err})
1704 }
mpagenko900ee4b2020-10-12 11:56:34 +00001705}
1706
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1708 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001709 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001711 voltha.OperStatus_ACTIVE); err != nil {
1712 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001714 }
1715
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001717 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001718 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001720
1721 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001723
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001725 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001727 return
1728 }
1729 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 if err := dh.storePersistentData(ctx); err != nil {
1731 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001732 log.Fields{"device-id": dh.deviceID, "err": err})
1733 }
mpagenko900ee4b2020-10-12 11:56:34 +00001734}
1735
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001737 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001739 // attention: the device reason update is done based on ONU-UNI-Port related activity
1740 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001741 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001742 // 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 +00001743 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301744 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001745 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001747 }
1748 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001750 // attention: the device reason update is done based on ONU-UNI-Port related activity
1751 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001752 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001753 // 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 +00001754 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001755 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001756 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301757}
1758
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1760 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001761 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301762 // attention: the device reason update is done based on ONU-UNI-Port related activity
1763 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301764
mpagenkofc4f56e2020-11-04 17:17:49 +00001765 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001766 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001767 // which may be the case from some previous actvity on another UNI Port of the ONU
1768 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001770 // request MDS-value for test and logging purposes
1771 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001772 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001774 }
1775 }
1776 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001777 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001778 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001780 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301781 }
1782}
1783
Himani Chawla6d2ae152020-09-02 13:11:20 +05301784//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301786 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001787 case MibDatabaseSync:
1788 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001790 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001791 case UniLockStateDone:
1792 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001794 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001795 case MibDownloadDone:
1796 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001798 }
1799 case UniUnlockStateDone:
1800 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001802 }
mpagenko900ee4b2020-10-12 11:56:34 +00001803 case UniEnableStateDone:
1804 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001806 }
1807 case UniDisableStateDone:
1808 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001809 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001810 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001811 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001812 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001814 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001815 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001816 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001818 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001819 default:
1820 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001822 }
1823 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001824}
1825
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001827 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301829 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001830 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001832 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301833 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001835 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001837 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001838 //store UniPort with the System-PortNumber key
1839 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001840 if !dh.reconciling {
1841 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1843 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001844 } //error logging already within UniPort method
1845 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001847 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848 }
1849 }
1850}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001851
mpagenko3af1f032020-06-10 08:53:41 +00001852// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001854 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301855 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001856 // with following remark:
1857 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1858 // # load on the core
1859
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001860 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001861
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001862 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001863 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301864 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301866 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001867 if !dh.reconciling {
1868 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 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 +00001870 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001871 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001873 }
mpagenko3af1f032020-06-10 08:53:41 +00001874 }
1875 }
1876}
1877
1878// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001880 // compare enableUniPortStateUpdate() above
1881 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1882 for uniNo, uniPort := range dh.uniEntityMap {
1883 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301884 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301886 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001887 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888 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 +00001889 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001890 }
1891}
1892
1893// ONU_Active/Inactive announcement on system KAFKA bus
1894// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001896 var de voltha.DeviceEvent
1897 eventContext := make(map[string]string)
1898 //Populating event context
1899 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001901 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301903 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001904 }
1905 oltSerialNumber := parentDevice.SerialNumber
1906
1907 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1908 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1909 eventContext["serial-number"] = dh.device.SerialNumber
1910 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301911 eventContext["device_id"] = aDeviceID
1912 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001913 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001914 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001915
1916 /* Populating device event body */
1917 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301918 de.ResourceId = aDeviceID
1919 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001920 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1921 de.Description = fmt.Sprintf("%s Event - %s - %s",
1922 cEventObjectType, cOnuActivatedEvent, "Raised")
1923 } else {
1924 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1925 de.Description = fmt.Sprintf("%s Event - %s - %s",
1926 cEventObjectType, cOnuActivatedEvent, "Cleared")
1927 }
1928 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1930 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301931 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001932 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301934 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001935}
1936
Himani Chawla4d908332020-08-31 12:30:20 +05301937// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001939 chLSFsm := make(chan Message, 2048)
1940 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301941 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001943 sFsmName = "LockStateFSM"
1944 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001946 sFsmName = "UnLockStateFSM"
1947 }
mpagenko3af1f032020-06-10 08:53:41 +00001948
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001950 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001952 return
1953 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001955 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001956 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301957 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001958 dh.pLockStateFsm = pLSFsm
1959 } else {
1960 dh.pUnlockStateFsm = pLSFsm
1961 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001963 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001965 }
1966}
1967
1968// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001970 /* Uni Port lock/unlock procedure -
1971 ***** should run via 'adminDone' state and generate the argument requested event *****
1972 */
1973 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301974 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001975 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1976 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1977 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001978 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301979 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001980 }
1981 } else {
1982 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1983 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1984 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001985 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301986 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001987 }
1988 }
1989 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001990 if pLSStatemachine.Is(uniStDisabled) {
1991 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001993 // maybe try a FSM reset and then again ... - TODO!!!
1994 } else {
1995 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001997 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001998 }
1999 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002001 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002002 // maybe try a FSM reset and then again ... - TODO!!!
2003 }
2004 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002006 // maybe try a FSM reset and then again ... - TODO!!!
2007 }
2008}
2009
Himani Chawla6d2ae152020-09-02 13:11:20 +05302010//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002012 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002014 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002015 kvbackend := &db.Backend{
2016 Client: dh.pOpenOnuAc.kvClient,
2017 StoreType: dh.pOpenOnuAc.KVStoreType,
2018 /* address config update acc. to [VOL-2736] */
2019 Address: addr,
2020 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2021 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002022
mpagenkoaf801632020-07-03 10:00:42 +00002023 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002024}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302026 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002027
mpagenkodff5dda2020-08-28 11:52:01 +00002028 for _, field := range flow.GetOfbFields(apFlowItem) {
2029 switch field.Type {
2030 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2031 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002033 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2034 }
mpagenko01e726e2020-10-23 09:45:29 +00002035 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002036 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2037 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302038 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002039 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302040 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2041 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002042 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2043 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002044 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2045 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302046 return
mpagenkodff5dda2020-08-28 11:52:01 +00002047 }
2048 }
mpagenko01e726e2020-10-23 09:45:29 +00002049 */
mpagenkodff5dda2020-08-28 11:52:01 +00002050 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2051 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302052 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002053 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302054 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002055 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302056 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002057 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302059 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002060 }
2061 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2062 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302063 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002065 "PCP": loAddPcp})
2066 }
2067 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2068 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002069 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002070 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2071 }
2072 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2073 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002075 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2076 }
2077 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2078 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002080 "IPv4-DST": field.GetIpv4Dst()})
2081 }
2082 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2083 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002085 "IPv4-SRC": field.GetIpv4Src()})
2086 }
2087 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2088 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002090 "Metadata": field.GetTableMetadata()})
2091 }
2092 /*
2093 default:
2094 {
2095 //all other entires ignored
2096 }
2097 */
2098 }
2099 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302100}
mpagenkodff5dda2020-08-28 11:52:01 +00002101
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002103 for _, action := range flow.GetActions(apFlowItem) {
2104 switch action.Type {
2105 /* not used:
2106 case of.OfpActionType_OFPAT_OUTPUT:
2107 {
mpagenko01e726e2020-10-23 09:45:29 +00002108 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002109 "Output": action.GetOutput()})
2110 }
2111 */
2112 case of.OfpActionType_OFPAT_PUSH_VLAN:
2113 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002115 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2116 }
2117 case of.OfpActionType_OFPAT_SET_FIELD:
2118 {
2119 pActionSetField := action.GetSetField()
2120 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002121 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002122 "OxcmClass": pActionSetField.Field.OxmClass})
2123 }
2124 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302127 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002128 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302129 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302131 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002132 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002134 "Type": pActionSetField.Field.GetOfbField().Type})
2135 }
2136 }
2137 /*
2138 default:
2139 {
2140 //all other entires ignored
2141 }
2142 */
2143 }
2144 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302145}
2146
2147//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302149 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2150 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2151 var loAddPcp, loSetPcp uint8
2152 var loIPProto uint32
2153 /* the TechProfileId is part of the flow Metadata - compare also comment within
2154 * OLT-Adapter:openolt_flowmgr.go
2155 * Metadata 8 bytes:
2156 * Most Significant 2 Bytes = Inner VLAN
2157 * Next 2 Bytes = Tech Profile ID(TPID)
2158 * Least Significant 4 Bytes = Port ID
2159 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2160 * subscriber related flows.
2161 */
2162
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302164 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302166 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002167 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302168 }
mpagenko551a4d42020-12-08 18:09:20 +00002169 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002170 loCookie := apFlowItem.GetCookie()
2171 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002173 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302174
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002176 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302177 if loIPProto == 2 {
2178 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2179 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002180 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2181 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302182 return nil
2183 }
mpagenko01e726e2020-10-23 09:45:29 +00002184 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002186
2187 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002189 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2190 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2191 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2192 //TODO!!: Use DeviceId within the error response to rwCore
2193 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002194 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002195 }
2196 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002198 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2199 } else {
2200 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2201 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2202 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002204 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002206 }
mpagenko9a304ea2020-12-16 15:54:01 +00002207
2208 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2209 dh.lockVlanConfig.Lock()
2210 defer dh.lockVlanConfig.Unlock()
2211 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302212 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002214 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002215 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002217 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002218}
2219
2220//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002221func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002222 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2223 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2224 //no extra check is done on the rule parameters
2225 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2226 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2227 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2228 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002229 // - 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 +00002230 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002232
2233 /* TT related temporary workaround - should not be needed anymore
2234 for _, field := range flow.GetOfbFields(apFlowItem) {
2235 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2236 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002237 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002238 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2239 if loIPProto == 2 {
2240 // 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 +00002241 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002242 log.Fields{"device-id": dh.deviceID})
2243 return nil
2244 }
2245 }
2246 } //for all OfbFields
2247 */
2248
mpagenko9a304ea2020-12-16 15:54:01 +00002249 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2250 dh.lockVlanConfig.Lock()
2251 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002252 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002254 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002256 log.Fields{"device-id": dh.deviceID})
2257 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002258 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002260
mpagenko01e726e2020-10-23 09:45:29 +00002261 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002262}
2263
Himani Chawla26e555c2020-08-31 12:30:20 +05302264// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002265// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002266func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002267 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002268 chVlanFilterFsm := make(chan Message, 2048)
2269
dbainbri4d3a0dc2020-12-02 00:33:42 +00002270 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002271 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302273 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002274 }
2275
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002277 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2278 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002279 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302280 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002281 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2282 if pVlanFilterStatemachine != nil {
2283 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2284 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302286 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002287 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302290 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2291 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002292 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002293 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002294 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302295 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002296 }
2297 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002299 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302300 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002301 }
2302 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002303 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002304 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302305 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002306 }
2307 return nil
2308}
2309
mpagenkofc4f56e2020-11-04 17:17:49 +00002310//VerifyVlanConfigRequest checks on existence of a given uniPort
2311// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002312func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002313 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2314 var pCurrentUniPort *onuUniPort
2315 for _, uniPort := range dh.uniEntityMap {
2316 // only if this port is validated for operState transfer
2317 if uniPort.uniID == uint8(aUniID) {
2318 pCurrentUniPort = uniPort
2319 break //found - end search loop
2320 }
2321 }
2322 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002324 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2325 return
2326 }
mpagenko551a4d42020-12-08 18:09:20 +00002327 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002328}
2329
mpagenkodff5dda2020-08-28 11:52:01 +00002330//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002331func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002332 //TODO!! verify and start pending flow configuration
2333 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2334 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302335 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002336 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2337 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2338 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002339 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2340 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2341 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2342 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2343 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2344 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2345 } else {
2346 /***** UniVlanConfigFsm continued */
2347 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2348 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2349 "UniPort": apUniPort.portNo})
2350 }
2351 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2352 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2353 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2354 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2355 } else {
2356 /***** UniVlanConfigFsm continued */
2357 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2358 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2359 "UniPort": apUniPort.portNo})
2360 }
mpagenkodff5dda2020-08-28 11:52:01 +00002361 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002362 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2363 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002364 "UniPort": apUniPort.portNo})
2365 }
2366 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002367 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2368 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2369 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002370 }
2371 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002372 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002373 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002374 }
mpagenkodff5dda2020-08-28 11:52:01 +00002375 } // else: nothing to do
2376}
2377
2378//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2379// 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 +00002380func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2381 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002382 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2383 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302384 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002385}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002386
2387//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2388//available for potential reconcilement
2389
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002391
2392 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002393 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002394 return nil
2395 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002396 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002397
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002399 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002401 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2402 }
2403 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2404
2405 pDevEntry.lockOnuKVStoreMutex()
2406 defer pDevEntry.unlockOnuKVStoreMutex()
2407
2408 // deadline context to ensure completion of background routines waited for
2409 //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 +05302410 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002411 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2412
2413 pDevEntry.resetKvProcessingErrorIndication()
2414 var wg sync.WaitGroup
2415 wg.Add(1) // for the 1 go routine to finish
2416
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2418 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002419
2420 return pDevEntry.getKvProcessingErrorIndication()
2421}
2422
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002424 defer cancel() //ensure termination of context (may be pro forma)
2425 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002427 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002428}
2429
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002431
2432 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002433 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002434 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2436 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002437 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002438 return err
2439 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002441 return nil
2442 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002443 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002444 return nil
2445}
2446
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2448 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002449 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002450 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002451 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2452 }
2453 pDevEntry.lockOnuKVStoreMutex()
2454 defer pDevEntry.unlockOnuKVStoreMutex()
2455
2456 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2457 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2458
2459 pDevEntry.resetKvProcessingErrorIndication()
2460 var wg sync.WaitGroup
2461 wg.Add(1) // for the 1 go routine to finish
2462
2463 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002465
2466 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002468 return err
2469 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002470 return nil
2471}
2472
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002473func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2474 var errStr string = ""
2475 for _, err := range errS {
2476 if err != nil {
2477 errStr = errStr + err.Error() + " "
2478 }
2479 }
2480 if errStr != "" {
2481 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2482 }
2483 return nil
2484}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002485
2486// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2487func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2488 dh.lockDevice.RLock()
2489 defer dh.lockDevice.RUnlock()
2490 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2491 return uniPort.entityID, nil
2492 }
2493 return 0, errors.New("error-fetching-uni-port")
2494}