blob: de715016efec392080f9d37554d7dab94ecd3535 [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
Himani Chawla6d2ae152020-09-02 13:11:20 +0530912// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000913// #####################################################################################
914
915// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530916// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000917
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
919 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 +0000920}
921
922// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000924
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000926 var err error
927
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000928 // populate what we know. rest comes later after mib sync
929 dh.device.Root = false
930 dh.device.Vendor = "OpenONU"
931 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000932 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000933 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000934
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000935 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000936
937 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
939 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530940 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000941 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000943 log.Fields{"device-id": dh.deviceID})
944 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000945
Himani Chawla4d908332020-08-31 12:30:20 +0530946 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000947 dh.ponPortNumber = dh.device.ParentPortNo
948
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000949 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
950 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
951 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000953 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530954 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000955
956 /*
957 self._pon = PonPort.create(self, self._pon_port_number)
958 self._pon.add_peer(self.parent_id, self._pon_port_number)
959 self.logger.debug('adding-pon-port-to-agent',
960 type=self._pon.get_port().type,
961 admin_state=self._pon.get_port().admin_state,
962 oper_status=self._pon.get_port().oper_status,
963 )
964 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000965 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000967 var ponPortNo uint32 = 1
968 if dh.ponPortNumber != 0 {
969 ponPortNo = dh.ponPortNumber
970 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000971
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000972 pPonPort := &voltha.Port{
973 PortNo: ponPortNo,
974 Label: fmt.Sprintf("pon-%d", ponPortNo),
975 Type: voltha.Port_PON_ONU,
976 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530977 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000978 PortNo: ponPortNo}}, // Peer port is parent's port number
979 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
981 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000982 e.Cancel(err)
983 return
984 }
985 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000987 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000989}
990
991// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000993
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000995 var err error
996 /*
997 dh.Client = oop.NewOpenoltClient(dh.clientCon)
998 dh.pTransitionMap.Handle(ctx, GrpcConnected)
999 return nil
1000 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1002 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001003 e.Cancel(err)
1004 return
1005 }
1006
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001007 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001009 // reconcilement will be continued after mib download is done
1010 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001011 /*
1012 ############################################################################
1013 # Setup Alarm handler
1014 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1015 device.serial_number)
1016 ############################################################################
1017 # Setup PM configuration for this device
1018 # Pass in ONU specific options
1019 kwargs = {
1020 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1021 'heartbeat': self.heartbeat,
1022 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1023 }
1024 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1025 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1026 self.logical_device_id, device.serial_number,
1027 grouped=True, freq_override=False, **kwargs)
1028 pm_config = self._pm_metrics.make_proto()
1029 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1030 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1031 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1032
1033 # Note, ONU ID and UNI intf set in add_uni_port method
1034 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1035 ani_ports=[self._pon])
1036
1037 # Code to Run OMCI Test Action
1038 kwargs_omci_test_action = {
1039 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1040 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1041 }
1042 serial_number = device.serial_number
1043 self._test_request = OmciTestRequest(self.core_proxy,
1044 self.omci_agent, self.device_id,
1045 AniG, serial_number,
1046 self.logical_device_id,
1047 exclusive=False,
1048 **kwargs_omci_test_action)
1049
1050 self.enabled = True
1051 else:
1052 self.logger.info('onu-already-activated')
1053 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001055}
1056
1057// doStateConnected get the device info and update to voltha core
1058// for comparison of the original method (not that easy to uncomment): compare here:
1059// voltha-openolt-adapter/adaptercore/device_handler.go
1060// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001062
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301064 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001065 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001066 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001067}
1068
1069// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001071
dbainbri4d3a0dc2020-12-02 00:33:42 +00001072 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301073 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001075 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001076
1077 /*
1078 // Synchronous call to update device state - this method is run in its own go routine
1079 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1080 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001081 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 +00001082 return err
1083 }
1084 return nil
1085 */
1086}
1087
1088// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001092 var err error
1093
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001094 device := dh.device
1095 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001096 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001097 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001098 e.Cancel(err)
1099 return
1100 }
1101
1102 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001104 /*
1105 // Update the all ports state on that device to disable
1106 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001107 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108 return er
1109 }
1110
1111 //Update the device oper state and connection status
1112 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1113 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1114 dh.device = cloned
1115
1116 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001117 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001118 return er
1119 }
1120
1121 //get the child device for the parent device
1122 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1123 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001124 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125 return err
1126 }
1127 for _, onuDevice := range onuDevices.Items {
1128
1129 // Update onu state as down in onu adapter
1130 onuInd := oop.OnuIndication{}
1131 onuInd.OperState = "down"
1132 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1133 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1134 if er != nil {
1135 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001136 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001137 //Do not return here and continue to process other ONUs
1138 }
1139 }
1140 // * Discovered ONUs entries need to be cleared , since after OLT
1141 // is up, it starts sending discovery indications again* /
1142 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001143 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 return nil
1145 */
Himani Chawla4d908332020-08-31 12:30:20 +05301146 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001149}
1150
Himani Chawla6d2ae152020-09-02 13:11:20 +05301151// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001152// #################################################################################
1153
1154// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301155// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001156
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001157//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001158func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001159 dh.lockDevice.RLock()
1160 pOnuDeviceEntry := dh.pOnuOmciDevice
1161 if aWait && pOnuDeviceEntry == nil {
1162 //keep the read sema short to allow for subsequent write
1163 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001164 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001165 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1166 // so it might be needed to wait here for that event with some timeout
1167 select {
1168 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001170 return nil
1171 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001173 // if written now, we can return the written value without sema
1174 return dh.pOnuOmciDevice
1175 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001176 }
mpagenko3af1f032020-06-10 08:53:41 +00001177 dh.lockDevice.RUnlock()
1178 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001179}
1180
Himani Chawla6d2ae152020-09-02 13:11:20 +05301181//setOnuDeviceEntry sets the ONU device entry within the handler
1182func (dh *deviceHandler) setOnuDeviceEntry(
1183 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001184 dh.lockDevice.Lock()
1185 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001186 dh.pOnuOmciDevice = apDeviceEntry
1187 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001188}
1189
Himani Chawla6d2ae152020-09-02 13:11:20 +05301190//addOnuDeviceEntry creates a new ONU device or returns the existing
1191func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001192 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001193
dbainbri4d3a0dc2020-12-02 00:33:42 +00001194 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001195 if deviceEntry == nil {
1196 /* costum_me_map in python code seems always to be None,
1197 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1198 /* also no 'clock' argument - usage open ...*/
1199 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001200 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001201 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001202 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301203 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001204 // fire deviceEntry ready event to spread to possibly waiting processing
1205 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001207 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001209 }
1210 // might be updated with some error handling !!!
1211 return nil
1212}
1213
dbainbri4d3a0dc2020-12-02 00:33:42 +00001214func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1215 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001216 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1217
1218 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001219
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001221 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001223 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1224 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001225 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 if err := dh.storePersistentData(ctx); err != nil {
1227 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001228 log.Fields{"device-id": dh.deviceID, "err": err})
1229 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001231 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001232 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001233 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1234 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001236 }
1237 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001239 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001240
1241 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 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 +00001243 log.Fields{"device-id": dh.deviceID})
1244 dh.reconciling = false
1245 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001246 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001247 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1248 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1249 // 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 +00001250 // 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 +00001251 // so let's just try to keep it simple ...
1252 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001254 if err != nil || device == nil {
1255 //TODO: needs to handle error scenarios
1256 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1257 return errors.New("Voltha Device not found")
1258 }
1259 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260
dbainbri4d3a0dc2020-12-02 00:33:42 +00001261 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001262 return err
mpagenko3af1f032020-06-10 08:53:41 +00001263 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001264
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001266
1267 /* this might be a good time for Omci Verify message? */
1268 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001270 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001271 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001273
1274 /* give the handler some time here to wait for the OMCi verification result
1275 after Timeout start and try MibUpload FSM anyway
1276 (to prevent stopping on just not supported OMCI verification from ONU) */
1277 select {
1278 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001280 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001282 }
1283
1284 /* In py code it looks earlier (on activate ..)
1285 # Code to Run OMCI Test Action
1286 kwargs_omci_test_action = {
1287 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1288 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1289 }
1290 serial_number = device.serial_number
1291 self._test_request = OmciTestRequest(self.core_proxy,
1292 self.omci_agent, self.device_id,
1293 AniG, serial_number,
1294 self.logical_device_id,
1295 exclusive=False,
1296 **kwargs_omci_test_action)
1297 ...
1298 # Start test requests after a brief pause
1299 if not self._test_request_started:
1300 self._test_request_started = True
1301 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1302 reactor.callLater(tststart, self._test_request.start_collector)
1303
1304 */
1305 /* which is then: in omci_test_request.py : */
1306 /*
1307 def start_collector(self, callback=None):
1308 """
1309 Start the collection loop for an adapter if the frequency > 0
1310
1311 :param callback: (callable) Function to call to collect PM data
1312 """
1313 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1314 if callback is None:
1315 callback = self.perform_test_omci
1316
1317 if self.lc is None:
1318 self.lc = LoopingCall(callback)
1319
1320 if self.default_freq > 0:
1321 self.lc.start(interval=self.default_freq / 10)
1322
1323 def perform_test_omci(self):
1324 """
1325 Perform the initial test request
1326 """
1327 ani_g_entities = self._device.configuration.ani_g_entities
1328 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1329 is not None else None
1330 self._entity_id = ani_g_entities_ids[0]
1331 self.logger.info('perform-test', entity_class=self._entity_class,
1332 entity_id=self._entity_id)
1333 try:
1334 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1335 result = yield self._device.omci_cc.send(frame)
1336 if not result.fields['omci_message'].fields['success_code']:
1337 self.logger.info('Self-Test Submitted Successfully',
1338 code=result.fields[
1339 'omci_message'].fields['success_code'])
1340 else:
1341 raise TestFailure('Test Failure: {}'.format(
1342 result.fields['omci_message'].fields['success_code']))
1343 except TimeoutError as e:
1344 self.deferred.errback(failure.Failure(e))
1345
1346 except Exception as e:
1347 self.logger.exception('perform-test-Error', e=e,
1348 class_id=self._entity_class,
1349 entity_id=self._entity_id)
1350 self.deferred.errback(failure.Failure(e))
1351
1352 */
1353
1354 // PM related heartbeat??? !!!TODO....
1355 //self._heartbeat.enabled = True
1356
mpagenko1cc3cb42020-07-27 15:24:38 +00001357 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1358 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1359 * 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 +05301360 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001361 */
1362 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001363 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001364 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001365 if pMibUlFsm.Is(ulStDisabled) {
1366 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001367 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 +00001368 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301369 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001370 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301371 //Determine ONU status and start/re-start MIB Synchronization tasks
1372 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001373 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301374 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001375 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 +00001376 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001377 }
Himani Chawla4d908332020-08-31 12:30:20 +05301378 } else {
1379 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001380 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 +00001381 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301382 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001383 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001384 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001385 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001386 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001387 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001388 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001389 }
1390 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001391 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001392 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001393 }
1394 return nil
1395}
1396
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001398 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001399 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001400 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001402
mpagenko900ee4b2020-10-12 11:56:34 +00001403 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1404 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1405 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001406 if err := dh.resetFsms(ctx); err != nil {
1407 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001408 log.Fields{"device-id": dh.deviceID, "error": err})
1409 // abort: system behavior is just unstable ...
1410 return err
1411 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001412 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 _ = 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 +00001414
1415 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1416 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1417 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001419 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001421 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001422 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001424
1425 //TODO!!! remove existing traffic profiles
1426 /* from py code, if TP's exist, remove them - not yet implemented
1427 self._tp = dict()
1428 # Let TP download happen again
1429 for uni_id in self._tp_service_specific_task:
1430 self._tp_service_specific_task[uni_id].clear()
1431 for uni_id in self._tech_profile_download_done:
1432 self._tech_profile_download_done[uni_id].clear()
1433 */
1434
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001436
mpagenkofc4f56e2020-11-04 17:17:49 +00001437 dh.ReadyForSpecificOmciConfig = false
1438
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001440 // abort: system behavior is just unstable ...
1441 return err
1442 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001444 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001446 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001447 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001449 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001450 // abort: system behavior is just unstable ...
1451 return err
1452 }
1453 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001454 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001455 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001456 return nil
1457}
1458
dbainbri4d3a0dc2020-12-02 00:33:42 +00001459func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001460 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1461 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1462 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1463 // and using the stop/reset event should never harm
1464
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001466 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001468 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1469 }
mpagenko900ee4b2020-10-12 11:56:34 +00001470 //the MibSync FSM might be active all the ONU-active time,
1471 // hence it must be stopped unconditionally
1472 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1473 if pMibUlFsm != nil {
1474 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1475 }
1476 //MibDownload may run
1477 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1478 if pMibDlFsm != nil {
1479 _ = pMibDlFsm.Event(dlEvReset)
1480 }
1481 //port lock/unlock FSM's may be active
1482 if dh.pUnlockStateFsm != nil {
1483 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1484 }
1485 if dh.pLockStateFsm != nil {
1486 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1487 }
1488 //techProfile related PonAniConfigFsm FSM may be active
1489 if dh.pOnuTP != nil {
1490 // should always be the case here
1491 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1492 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001493 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1494 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1495 }
mpagenko900ee4b2020-10-12 11:56:34 +00001496 }
1497 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001498 // reset the possibly existing VlanConfigFsm
1499 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1500 //VlanFilterFsm exists and was already started
1501 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1502 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001503 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001504 // no need to remove specific data
1505 pVlanFilterFsm.RequestClearPersistency(false)
1506 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001507 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1508 }
1509 }
1510 }
1511 }
1512 //TODO!!! care about PM/Alarm processing once started
1513 return nil
1514}
1515
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1517 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 +05301518
dbainbri4d3a0dc2020-12-02 00:33:42 +00001519 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1520 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001521 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001523 return
1524 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001525 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001526 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1527 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1528 for _, mgmtEntityID := range pptpInstKeys {
1529 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1530 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301532 i++
1533 }
1534 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001535 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301536 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001537 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1538 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301539 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001540 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301541 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301543 i++
1544 }
1545 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001546 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301547 }
1548 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301550 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001551 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1552 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1553 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1554 * disable/enable toggling here to allow traffic
1555 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1556 * like the py comment says:
1557 * # start by locking all the unis till mib sync and initial mib is downloaded
1558 * # this way we can capture the port down/up events when we are ready
1559 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301560
mpagenkoa40e99a2020-11-17 13:50:39 +00001561 // Init Uni Ports to Admin locked state
1562 // *** should generate UniLockStateDone event *****
1563 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001564 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001565 } else { //LockStateFSM already init
1566 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001568 }
1569}
1570
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1572 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301573 /* Mib download procedure -
1574 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1575 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001576 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001577 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001579 return
1580 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301581 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1582 if pMibDlFsm != nil {
1583 if pMibDlFsm.Is(dlStDisabled) {
1584 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585 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 +05301586 // maybe try a FSM reset and then again ... - TODO!!!
1587 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301589 // maybe use more specific states here for the specific download steps ...
1590 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001591 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301592 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001593 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301594 //Begin MIB data download (running autonomously)
1595 }
1596 }
1597 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001599 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301600 // maybe try a FSM reset and then again ... - TODO!!!
1601 }
1602 /***** Mib download started */
1603 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301605 }
1606}
1607
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1609 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301610 //initiate DevStateUpdate
1611 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001613 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301615 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1616 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301618 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301620 }
1621 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001623 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001625 return
1626 }
1627 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 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 +00001629 log.Fields{"device-id": dh.deviceID})
1630 dh.reconciling = false
1631 return
1632 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301634 log.Fields{"device-id": dh.deviceID})
1635 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001637 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301638 // *** should generate UniUnlockStateDone event *****
1639 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301641 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301642 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301644 }
1645}
1646
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1648 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301649
1650 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301652 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1654 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001655 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001657 return
1658 }
1659 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 if err := dh.storePersistentData(ctx); err != nil {
1661 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001662 log.Fields{"device-id": dh.deviceID, "err": err})
1663 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301664 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 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 +05301666 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001668 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301669 }
1670}
1671
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1673 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001674 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001676 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1677 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001679 }
1680
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001682 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001684
1685 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001687
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001689 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001691 return
1692 }
1693 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 if err := dh.storePersistentData(ctx); err != nil {
1695 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001696 log.Fields{"device-id": dh.deviceID, "err": err})
1697 }
mpagenko900ee4b2020-10-12 11:56:34 +00001698}
1699
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1701 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001702 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001704 voltha.OperStatus_ACTIVE); err != nil {
1705 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001707 }
1708
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001710 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001711 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001713
1714 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001716
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001718 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001720 return
1721 }
1722 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 if err := dh.storePersistentData(ctx); err != nil {
1724 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001725 log.Fields{"device-id": dh.deviceID, "err": err})
1726 }
mpagenko900ee4b2020-10-12 11:56:34 +00001727}
1728
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001730 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001732 // attention: the device reason update is done based on ONU-UNI-Port related activity
1733 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001734 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001735 // 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 +00001736 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301737 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001738 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001740 }
1741 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001743 // attention: the device reason update is done based on ONU-UNI-Port related activity
1744 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001745 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001746 // 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 +00001747 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001748 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001749 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301750}
1751
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1753 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001754 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301755 // attention: the device reason update is done based on ONU-UNI-Port related activity
1756 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301757
mpagenkofc4f56e2020-11-04 17:17:49 +00001758 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001759 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001760 // which may be the case from some previous actvity on another UNI Port of the ONU
1761 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001763 // request MDS-value for test and logging purposes
1764 dh.pOnuOmciDevice.requestMdsValue(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001765 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001767 }
1768 }
1769 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001770 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001771 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001773 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301774 }
1775}
1776
Himani Chawla6d2ae152020-09-02 13:11:20 +05301777//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301779 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001780 case MibDatabaseSync:
1781 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001783 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001784 case UniLockStateDone:
1785 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001787 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001788 case MibDownloadDone:
1789 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001791 }
1792 case UniUnlockStateDone:
1793 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001795 }
mpagenko900ee4b2020-10-12 11:56:34 +00001796 case UniEnableStateDone:
1797 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001799 }
1800 case UniDisableStateDone:
1801 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001803 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001804 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001805 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001807 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001808 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001809 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001811 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001812 default:
1813 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001815 }
1816 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817}
1818
dbainbri4d3a0dc2020-12-02 00:33:42 +00001819func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001820 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301822 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001823 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001825 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301826 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001830 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001831 //store UniPort with the System-PortNumber key
1832 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001833 if !dh.reconciling {
1834 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1836 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001837 } //error logging already within UniPort method
1838 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001840 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001841 }
1842 }
1843}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001844
mpagenko3af1f032020-06-10 08:53:41 +00001845// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001847 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301848 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001849 // with following remark:
1850 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1851 // # load on the core
1852
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001853 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001854
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001855 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001856 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301857 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001858 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301859 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001860 if !dh.reconciling {
1861 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 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 +00001863 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001864 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001866 }
mpagenko3af1f032020-06-10 08:53:41 +00001867 }
1868 }
1869}
1870
1871// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001873 // compare enableUniPortStateUpdate() above
1874 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1875 for uniNo, uniPort := range dh.uniEntityMap {
1876 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301877 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301879 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001880 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 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 +00001882 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001883 }
1884}
1885
1886// ONU_Active/Inactive announcement on system KAFKA bus
1887// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001889 var de voltha.DeviceEvent
1890 eventContext := make(map[string]string)
1891 //Populating event context
1892 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001894 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301896 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001897 }
1898 oltSerialNumber := parentDevice.SerialNumber
1899
1900 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1901 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1902 eventContext["serial-number"] = dh.device.SerialNumber
1903 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301904 eventContext["device_id"] = aDeviceID
1905 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001907 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001908
1909 /* Populating device event body */
1910 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301911 de.ResourceId = aDeviceID
1912 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001913 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1914 de.Description = fmt.Sprintf("%s Event - %s - %s",
1915 cEventObjectType, cOnuActivatedEvent, "Raised")
1916 } else {
1917 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1918 de.Description = fmt.Sprintf("%s Event - %s - %s",
1919 cEventObjectType, cOnuActivatedEvent, "Cleared")
1920 }
1921 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1923 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301924 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001925 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001926 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301927 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001928}
1929
Himani Chawla4d908332020-08-31 12:30:20 +05301930// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001932 chLSFsm := make(chan Message, 2048)
1933 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301934 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001935 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001936 sFsmName = "LockStateFSM"
1937 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001939 sFsmName = "UnLockStateFSM"
1940 }
mpagenko3af1f032020-06-10 08:53:41 +00001941
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001943 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001945 return
1946 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001947 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001948 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001949 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301950 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001951 dh.pLockStateFsm = pLSFsm
1952 } else {
1953 dh.pUnlockStateFsm = pLSFsm
1954 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001956 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001958 }
1959}
1960
1961// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001963 /* Uni Port lock/unlock procedure -
1964 ***** should run via 'adminDone' state and generate the argument requested event *****
1965 */
1966 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301967 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001968 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1969 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1970 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001971 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301972 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001973 }
1974 } else {
1975 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1976 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1977 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001978 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301979 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001980 }
1981 }
1982 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001983 if pLSStatemachine.Is(uniStDisabled) {
1984 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001985 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001986 // maybe try a FSM reset and then again ... - TODO!!!
1987 } else {
1988 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001990 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001991 }
1992 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001994 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001995 // maybe try a FSM reset and then again ... - TODO!!!
1996 }
1997 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001999 // maybe try a FSM reset and then again ... - TODO!!!
2000 }
2001}
2002
Himani Chawla6d2ae152020-09-02 13:11:20 +05302003//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002005 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002006 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002007 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002008 kvbackend := &db.Backend{
2009 Client: dh.pOpenOnuAc.kvClient,
2010 StoreType: dh.pOpenOnuAc.KVStoreType,
2011 /* address config update acc. to [VOL-2736] */
2012 Address: addr,
2013 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2014 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002015
mpagenkoaf801632020-07-03 10:00:42 +00002016 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002017}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002018func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302019 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002020
mpagenkodff5dda2020-08-28 11:52:01 +00002021 for _, field := range flow.GetOfbFields(apFlowItem) {
2022 switch field.Type {
2023 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2024 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002026 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2027 }
mpagenko01e726e2020-10-23 09:45:29 +00002028 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002029 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2030 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302031 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002032 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302033 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2034 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002035 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2036 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002037 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2038 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302039 return
mpagenkodff5dda2020-08-28 11:52:01 +00002040 }
2041 }
mpagenko01e726e2020-10-23 09:45:29 +00002042 */
mpagenkodff5dda2020-08-28 11:52:01 +00002043 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2044 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302045 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002046 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302047 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002048 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302049 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002050 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302052 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002053 }
2054 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2055 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302056 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002058 "PCP": loAddPcp})
2059 }
2060 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2061 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002063 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2064 }
2065 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2066 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002068 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2069 }
2070 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2071 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002073 "IPv4-DST": field.GetIpv4Dst()})
2074 }
2075 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2076 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002078 "IPv4-SRC": field.GetIpv4Src()})
2079 }
2080 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2081 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002083 "Metadata": field.GetTableMetadata()})
2084 }
2085 /*
2086 default:
2087 {
2088 //all other entires ignored
2089 }
2090 */
2091 }
2092 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302093}
mpagenkodff5dda2020-08-28 11:52:01 +00002094
dbainbri4d3a0dc2020-12-02 00:33:42 +00002095func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002096 for _, action := range flow.GetActions(apFlowItem) {
2097 switch action.Type {
2098 /* not used:
2099 case of.OfpActionType_OFPAT_OUTPUT:
2100 {
mpagenko01e726e2020-10-23 09:45:29 +00002101 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002102 "Output": action.GetOutput()})
2103 }
2104 */
2105 case of.OfpActionType_OFPAT_PUSH_VLAN:
2106 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002108 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2109 }
2110 case of.OfpActionType_OFPAT_SET_FIELD:
2111 {
2112 pActionSetField := action.GetSetField()
2113 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002115 "OxcmClass": pActionSetField.Field.OxmClass})
2116 }
2117 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302118 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302120 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002121 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302122 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302124 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002125 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002127 "Type": pActionSetField.Field.GetOfbField().Type})
2128 }
2129 }
2130 /*
2131 default:
2132 {
2133 //all other entires ignored
2134 }
2135 */
2136 }
2137 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302138}
2139
2140//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2143 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2144 var loAddPcp, loSetPcp uint8
2145 var loIPProto uint32
2146 /* the TechProfileId is part of the flow Metadata - compare also comment within
2147 * OLT-Adapter:openolt_flowmgr.go
2148 * Metadata 8 bytes:
2149 * Most Significant 2 Bytes = Inner VLAN
2150 * Next 2 Bytes = Tech Profile ID(TPID)
2151 * Least Significant 4 Bytes = Port ID
2152 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2153 * subscriber related flows.
2154 */
2155
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302159 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002160 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302161 }
mpagenko551a4d42020-12-08 18:09:20 +00002162 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002163 loCookie := apFlowItem.GetCookie()
2164 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002166 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302167
dbainbri4d3a0dc2020-12-02 00:33:42 +00002168 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002169 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302170 if loIPProto == 2 {
2171 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2172 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002173 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2174 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 return nil
2176 }
mpagenko01e726e2020-10-23 09:45:29 +00002177 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002178 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002179
2180 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002182 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2183 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2184 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2185 //TODO!!: Use DeviceId within the error response to rwCore
2186 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002187 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002188 }
2189 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002191 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2192 } else {
2193 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2194 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2195 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302196 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002197 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002199 }
mpagenko9a304ea2020-12-16 15:54:01 +00002200
2201 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2202 dh.lockVlanConfig.Lock()
2203 defer dh.lockVlanConfig.Unlock()
2204 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302205 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002207 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002208 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002210 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002211}
2212
2213//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002214func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002215 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2216 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2217 //no extra check is done on the rule parameters
2218 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2219 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2220 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2221 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002222 // - 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 +00002223 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002225
2226 /* TT related temporary workaround - should not be needed anymore
2227 for _, field := range flow.GetOfbFields(apFlowItem) {
2228 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2229 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002230 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002231 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2232 if loIPProto == 2 {
2233 // 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 +00002234 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002235 log.Fields{"device-id": dh.deviceID})
2236 return nil
2237 }
2238 }
2239 } //for all OfbFields
2240 */
2241
mpagenko9a304ea2020-12-16 15:54:01 +00002242 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2243 dh.lockVlanConfig.Lock()
2244 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002245 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002247 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002248 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002249 log.Fields{"device-id": dh.deviceID})
2250 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002251 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002253
mpagenko01e726e2020-10-23 09:45:29 +00002254 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002255}
2256
Himani Chawla26e555c2020-08-31 12:30:20 +05302257// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002258// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002259func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002260 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002261 chVlanFilterFsm := make(chan Message, 2048)
2262
dbainbri4d3a0dc2020-12-02 00:33:42 +00002263 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002264 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302266 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002267 }
2268
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002270 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2271 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002272 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302273 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002274 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2275 if pVlanFilterStatemachine != nil {
2276 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2277 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002278 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302279 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002280 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302281 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002282 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302283 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2284 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002285 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002287 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002289 }
2290 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002291 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002292 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302293 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002294 }
2295 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002297 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302298 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002299 }
2300 return nil
2301}
2302
mpagenkofc4f56e2020-11-04 17:17:49 +00002303//VerifyVlanConfigRequest checks on existence of a given uniPort
2304// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002305func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002306 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2307 var pCurrentUniPort *onuUniPort
2308 for _, uniPort := range dh.uniEntityMap {
2309 // only if this port is validated for operState transfer
2310 if uniPort.uniID == uint8(aUniID) {
2311 pCurrentUniPort = uniPort
2312 break //found - end search loop
2313 }
2314 }
2315 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002317 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2318 return
2319 }
mpagenko551a4d42020-12-08 18:09:20 +00002320 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002321}
2322
mpagenkodff5dda2020-08-28 11:52:01 +00002323//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002324func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002325 //TODO!! verify and start pending flow configuration
2326 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2327 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302328 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002329 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2330 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2331 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002332 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2333 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2334 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2335 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2336 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2337 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2338 } else {
2339 /***** UniVlanConfigFsm continued */
2340 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2341 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2342 "UniPort": apUniPort.portNo})
2343 }
2344 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2345 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2346 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2347 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2348 } else {
2349 /***** UniVlanConfigFsm continued */
2350 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2351 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2352 "UniPort": apUniPort.portNo})
2353 }
mpagenkodff5dda2020-08-28 11:52:01 +00002354 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002355 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2356 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002357 "UniPort": apUniPort.portNo})
2358 }
2359 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002360 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2361 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2362 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002363 }
2364 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002365 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002366 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002367 }
mpagenkodff5dda2020-08-28 11:52:01 +00002368 } // else: nothing to do
2369}
2370
2371//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2372// 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 +00002373func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2374 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002375 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2376 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002378}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002379
2380//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2381//available for potential reconcilement
2382
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002384
2385 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002387 return nil
2388 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002390
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002392 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002393 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002394 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2395 }
2396 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2397
2398 pDevEntry.lockOnuKVStoreMutex()
2399 defer pDevEntry.unlockOnuKVStoreMutex()
2400
2401 // deadline context to ensure completion of background routines waited for
2402 //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 +05302403 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002404 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2405
2406 pDevEntry.resetKvProcessingErrorIndication()
2407 var wg sync.WaitGroup
2408 wg.Add(1) // for the 1 go routine to finish
2409
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2411 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002412
2413 return pDevEntry.getKvProcessingErrorIndication()
2414}
2415
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002417 defer cancel() //ensure termination of context (may be pro forma)
2418 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002419 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002420 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002421}
2422
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002424
2425 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002426 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002427 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2429 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002430 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002431 return err
2432 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002433 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002434 return nil
2435 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002437 return nil
2438}
2439
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2441 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002442 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002443 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002444 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2445 }
2446 pDevEntry.lockOnuKVStoreMutex()
2447 defer pDevEntry.unlockOnuKVStoreMutex()
2448
2449 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2450 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2451
2452 pDevEntry.resetKvProcessingErrorIndication()
2453 var wg sync.WaitGroup
2454 wg.Add(1) // for the 1 go routine to finish
2455
2456 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002458
2459 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002461 return err
2462 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002463 return nil
2464}
2465
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002466func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2467 var errStr string = ""
2468 for _, err := range errS {
2469 if err != nil {
2470 errStr = errStr + err.Error() + " "
2471 }
2472 }
2473 if errStr != "" {
2474 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2475 }
2476 return nil
2477}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002478
2479// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2480func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2481 dh.lockDevice.RLock()
2482 defer dh.lockDevice.RUnlock()
2483 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2484 return uniPort.entityID, nil
2485 }
2486 return 0, errors.New("error-fetching-uni-port")
2487}