blob: 7328abd4ca91c66dd68af99b100518a4a4eb4823 [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"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000033 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
mpagenkoaf801632020-07-03 10:00:42 +000034 "github.com/opencord/voltha-lib-go/v3/pkg/db"
mpagenkodff5dda2020-08-28 11:52:01 +000035 flow "github.com/opencord/voltha-lib-go/v3/pkg/flows"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000036 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000037 vc "github.com/opencord/voltha-protos/v3/go/common"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000038 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
mpagenkodff5dda2020-08-28 11:52:01 +000039 "github.com/opencord/voltha-protos/v3/go/openflow_13"
40 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
41 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000042 oop "github.com/opencord/voltha-protos/v3/go/openolt"
43 "github.com/opencord/voltha-protos/v3/go/voltha"
44)
45
46/*
47// Constants for number of retries and for timeout
48const (
49 MaxRetry = 10
50 MaxTimeOutInMs = 500
51)
52*/
53
mpagenko1cc3cb42020-07-27 15:24:38 +000054const (
55 // events of Device FSM
56 devEvDeviceInit = "devEvDeviceInit"
57 devEvGrpcConnected = "devEvGrpcConnected"
58 devEvGrpcDisconnected = "devEvGrpcDisconnected"
59 devEvDeviceUpInd = "devEvDeviceUpInd"
60 devEvDeviceDownInd = "devEvDeviceDownInd"
61)
62const (
63 // states of Device FSM
64 devStNull = "devStNull"
65 devStDown = "devStDown"
66 devStInit = "devStInit"
67 devStConnected = "devStConnected"
68 devStUp = "devStUp"
69)
70
Holger Hildebrandt24d51952020-05-04 14:03:42 +000071//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
72const (
Himani Chawla4d908332020-08-31 12:30:20 +053073 pon = voltha.EventSubCategory_PON
74 //olt = voltha.EventSubCategory_OLT
75 //ont = voltha.EventSubCategory_ONT
76 //onu = voltha.EventSubCategory_ONU
77 //nni = voltha.EventSubCategory_NNI
78 //service = voltha.EventCategory_SERVICE
79 //security = voltha.EventCategory_SECURITY
80 equipment = voltha.EventCategory_EQUIPMENT
81 //processing = voltha.EventCategory_PROCESSING
82 //environment = voltha.EventCategory_ENVIRONMENT
83 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000084)
85
86const (
87 cEventObjectType = "ONU"
88)
89const (
90 cOnuActivatedEvent = "ONU_ACTIVATED"
91)
92
Holger Hildebrandt80129db2020-11-23 10:49:32 +000093const (
94 // device reasons
95 drActivatingOnu = "activating-onu"
96 drStartingOpenomci = "starting-openomci"
97 drDiscoveryMibsyncComplete = "discovery-mibsync-complete"
98 drInitialMibDownloaded = "initial-mib-downloaded"
99 drTechProfileConfigDownloadSuccess = "tech-profile-config-download-success"
100 drOmciFlowsPushed = "omci-flows-pushed"
101 drOmciAdminLock = "omci-admin-lock"
102 drOnuReenabled = "onu-reenabled"
103 drStoppingOpenomci = "stopping-openomci"
104 drRebooting = "rebooting"
105 drOmciFlowsDeleted = "omci-flows-deleted"
106 drTechProfileConfigDeleteSuccess = "tech-profile-config-delete-success"
107)
108
Himani Chawla6d2ae152020-09-02 13:11:20 +0530109//deviceHandler will interact with the ONU ? device.
110type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000111 deviceID string
112 DeviceType string
113 adminState string
114 device *voltha.Device
115 logicalDeviceID string
116 ProxyAddressID string
117 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530118 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000119 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000120
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000121 coreProxy adapterif.CoreProxy
122 AdapterProxy adapterif.AdapterProxy
123 EventProxy adapterif.EventProxy
124
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000125 pOpenOnuAc *OpenONUAC
126 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530127 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000128 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000129 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530130 pOnuTP *onuUniTechProf
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000131 exitChannel chan int
132 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000133 pOnuIndication *oop.OnuIndication
mpagenko3af1f032020-06-10 08:53:41 +0000134 deviceReason string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530135 pLockStateFsm *lockStateFsm
136 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000137
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000138 //flowMgr *OpenOltFlowMgr
139 //eventMgr *OpenOltEventMgr
140 //resourceMgr *rsrcMgr.OpenOltResourceMgr
141
142 //discOnus sync.Map
143 //onus sync.Map
144 //portStats *OpenOltStatisticsMgr
145 //metrics *pmmetrics.PmMetrics
mpagenkofc4f56e2020-11-04 17:17:49 +0000146 stopCollector chan bool
147 stopHeartbeatCheck chan bool
148 activePorts sync.Map
149 uniEntityMap map[uint32]*onuUniPort
150 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
151 reconciling bool
152 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153}
154
Himani Chawla6d2ae152020-09-02 13:11:20 +0530155//newDeviceHandler creates a new device handler
156func newDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
157 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000158 dh.coreProxy = cp
159 dh.AdapterProxy = ap
160 dh.EventProxy = ep
161 cloned := (proto.Clone(device)).(*voltha.Device)
162 dh.deviceID = cloned.Id
163 dh.DeviceType = cloned.Type
164 dh.adminState = "up"
165 dh.device = cloned
166 dh.pOpenOnuAc = adapter
167 dh.exitChannel = make(chan int, 1)
168 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000169 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170 dh.stopCollector = make(chan bool, 2)
171 dh.stopHeartbeatCheck = make(chan bool, 2)
172 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
173 dh.activePorts = sync.Map{}
174 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530175 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000176 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000177 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000178 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000179
180 // Device related state machine
181 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000182 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000184 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
185 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
186 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
187 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
188 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000189 },
190 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000191 "before_event": func(e *fsm.Event) { dh.logStateChange(e) },
192 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(e) },
193 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(e) },
194 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(e) },
195 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
196 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(e) },
197 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(e) },
198 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000199 },
200 )
mpagenkoaf801632020-07-03 10:00:42 +0000201
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000202 return &dh
203}
204
Himani Chawla6d2ae152020-09-02 13:11:20 +0530205// start save the device to the data model
206func (dh *deviceHandler) start(ctx context.Context) {
divyadesai4d299552020-08-18 07:13:49 +0000207 logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000208 // Add the initial device to the local model
209 logger.Debug("device-handler-started")
210}
211
Himani Chawla4d908332020-08-31 12:30:20 +0530212/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000213// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530214func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 logger.Debug("stopping-device-handler")
216 dh.exitChannel <- 1
217}
Himani Chawla4d908332020-08-31 12:30:20 +0530218*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219
220// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530221// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222
Himani Chawla6d2ae152020-09-02 13:11:20 +0530223//adoptOrReconcileDevice adopts the OLT device
224func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000225 logger.Debugw("Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000226
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000227 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000228 if dh.pDeviceStateFsm.Is(devStNull) {
229 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230 logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
231 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000232 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 } else {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000234 logger.Debugw("AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 }
236
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
Himani Chawla6d2ae152020-09-02 13:11:20 +0530239func (dh *deviceHandler) processInterAdapterOMCIReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530240 msgBody := msg.GetBody()
241 omciMsg := &ic.InterAdapterOmciMessage{}
242 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
243 logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
244 "device-id": dh.deviceID, "error": err})
245 return err
246 }
247
248 //assuming omci message content is hex coded!
249 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
250 logger.Debugw("inter-adapter-recv-omci", log.Fields{
251 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
252 //receive_message(omci_msg.message)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530253 pDevEntry := dh.getOnuDeviceEntry(true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530254 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000255 if pDevEntry.PDevOmciCC != nil {
256 return pDevEntry.PDevOmciCC.receiveMessage(context.TODO(), omciMsg.Message)
257 }
258 logger.Debugw("omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530259 }
260 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000261 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530262}
263
Himani Chawla6d2ae152020-09-02 13:11:20 +0530264func (dh *deviceHandler) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530265 msgBody := msg.GetBody()
266 onuIndication := &oop.OnuIndication{}
267 if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000268 logger.Warnw("onu-ind-request-cannot-unmarshal-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530269 "device-id": dh.deviceID, "error": err})
270 return err
271 }
272
273 onuOperstate := onuIndication.GetOperState()
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000274 logger.Infow("onu-ind-request", log.Fields{"device-id": dh.deviceID,
mpagenko900ee4b2020-10-12 11:56:34 +0000275 "OnuId": onuIndication.GetOnuId(),
Himani Chawla26e555c2020-08-31 12:30:20 +0530276 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
277 "SNR": onuIndication.GetSerialNumber()})
278
279 //interface related functions might be error checked ....
280 if onuOperstate == "up" {
281 _ = dh.createInterface(onuIndication)
282 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
283 _ = dh.updateInterface(onuIndication)
284 } else {
285 logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000286 return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530287 }
288 return nil
289}
290
Himani Chawla6d2ae152020-09-02 13:11:20 +0530291func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530292 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000293
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000294 logger.Infow("tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
295
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000296 pDevEntry := dh.getOnuDeviceEntry(true)
297 if pDevEntry == nil {
298 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
299 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
300 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530301 if dh.pOnuTP == nil {
302 //should normally not happen ...
mpagenkoa40e99a2020-11-17 13:50:39 +0000303 logger.Errorw("onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530304 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000305 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530306 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000307 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000308 logger.Errorw("TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000309 "device-state": dh.deviceReason})
310 return fmt.Errorf("improper device state %s on device %s", dh.deviceReason, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530311 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000312 //previous state test here was just this one, now extended for more states to reject the SetRequest:
313 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
314 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530315
316 msgBody := msg.GetBody()
317 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
318 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
319 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
320 "device-id": dh.deviceID, "error": err})
321 return err
322 }
323
324 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000325 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
326 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000328 defer dh.pOnuTP.unlockTpProcMutex()
329 pDevEntry.lockOnuKVStoreMutex()
330 defer pDevEntry.unlockOnuKVStoreMutex()
331
332 if techProfMsg.UniId > 255 {
333 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
334 techProfMsg.UniId, dh.deviceID))
335 }
336 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800337 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
338 if err != nil {
339 logger.Errorw("error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
340 return err
341 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000342
Girish Gowdra041dcb32020-11-16 16:54:30 -0800343 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530344 // if there has been some change for some uni TechProfilePath
345 //in order to allow concurrent calls to other dh instances we do not wait for execution here
346 //but doing so we can not indicate problems to the caller (who does what with that then?)
347 //by now we just assume straightforward successful execution
348 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
349 // possible problems to the caller later autonomously
350
351 // deadline context to ensure completion of background routines waited for
352 //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 +0530353 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 dctx, cancel := context.WithDeadline(context.Background(), deadline)
355
Girish Gowdra041dcb32020-11-16 16:54:30 -0800356 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000357 pDevEntry.resetKvProcessingErrorIndication()
358
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 var wg sync.WaitGroup
360 wg.Add(2) // for the 2 go routines to finish
361 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000362 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
363 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000364 dh.waitForCompletion(cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365
Girish Gowdra041dcb32020-11-16 16:54:30 -0800366 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530369 return nil
370}
371
Himani Chawla6d2ae152020-09-02 13:11:20 +0530372func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 msg *ic.InterAdapterMessage) error {
374
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000375 logger.Infow("delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
376
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000377 pDevEntry := dh.getOnuDeviceEntry(true)
378 if pDevEntry == nil {
379 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
380 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
381 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 if dh.pOnuTP == nil {
383 //should normally not happen ...
384 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
385 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 }
388
389 msgBody := msg.GetBody()
390 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
391 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
392 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
393 "device-id": dh.deviceID, "error": err})
394 return err
395 }
396
397 //compare TECH_PROFILE_DOWNLOAD_REQUEST
398 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399 defer dh.pOnuTP.unlockTpProcMutex()
400 pDevEntry.lockOnuKVStoreMutex()
401 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530402
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403 if delGemPortMsg.UniId > 255 {
404 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
405 delGemPortMsg.UniId, dh.deviceID))
406 }
407 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800408 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
409 if err != nil {
410 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
411 return err
412 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530413
mpagenkofc4f56e2020-11-04 17:17:49 +0000414 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415
mpagenkofc4f56e2020-11-04 17:17:49 +0000416 // deadline context to ensure completion of background routines waited for
417 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
418 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419
Girish Gowdra041dcb32020-11-16 16:54:30 -0800420 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000421
mpagenkofc4f56e2020-11-04 17:17:49 +0000422 var wg sync.WaitGroup
423 wg.Add(1) // for the 1 go routine to finish
424 go dh.pOnuTP.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
425 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
426 dh.waitForCompletion(cancel, &wg, "GemDelete") //wait for background process to finish
427
Girish Gowdra041dcb32020-11-16 16:54:30 -0800428 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530429}
430
Himani Chawla6d2ae152020-09-02 13:11:20 +0530431func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530432 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000433
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000434 logger.Infow("delete-tcont-request", log.Fields{"device-id": dh.deviceID})
435
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 pDevEntry := dh.getOnuDeviceEntry(true)
437 if pDevEntry == nil {
438 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
439 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
440 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530441 if dh.pOnuTP == nil {
442 //should normally not happen ...
443 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
444 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 }
447
448 msgBody := msg.GetBody()
449 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
450 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
451 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
452 "device-id": dh.deviceID, "error": err})
453 return err
454 }
455
456 //compare TECH_PROFILE_DOWNLOAD_REQUEST
457 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000458 defer dh.pOnuTP.unlockTpProcMutex()
459 pDevEntry.lockOnuKVStoreMutex()
460 defer pDevEntry.unlockOnuKVStoreMutex()
461
462 if delTcontMsg.UniId > 255 {
463 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
464 delTcontMsg.UniId, dh.deviceID))
465 }
466 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800467 tpPath := delTcontMsg.TpPath
468 tpID, err := GetTpIDFromTpPath(tpPath)
469 if err != nil {
470 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
471 return err
472 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000473
Girish Gowdra041dcb32020-11-16 16:54:30 -0800474 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530476 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 dctx, cancel := context.WithDeadline(context.Background(), deadline)
478
Girish Gowdra041dcb32020-11-16 16:54:30 -0800479 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000480 pDevEntry.resetKvProcessingErrorIndication()
481
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 var wg sync.WaitGroup
483 wg.Add(2) // for the 2 go routines to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000484 go dh.pOnuTP.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 cResourceTcont, delTcontMsg.AllocId, &wg)
486 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000488 dh.waitForCompletion(cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000489
Girish Gowdra041dcb32020-11-16 16:54:30 -0800490 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 return nil
493}
494
Himani Chawla6d2ae152020-09-02 13:11:20 +0530495//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000496// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
497// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530498func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000499 msgID := msg.Header.Id
500 msgType := msg.Header.Type
501 fromTopic := msg.Header.FromTopic
502 toTopic := msg.Header.ToTopic
503 toDeviceID := msg.Header.ToDeviceId
504 proxyDeviceID := msg.Header.ProxyDeviceId
505 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
506 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
507
508 switch msgType {
509 case ic.InterAdapterMessageType_OMCI_REQUEST:
510 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530511 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000512 }
513 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
514 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000516 }
mpagenkoaf801632020-07-03 10:00:42 +0000517 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
518 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530519 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000520 }
521 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
522 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530523 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000524
mpagenkoaf801632020-07-03 10:00:42 +0000525 }
526 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
527 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530528 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000529 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000530 default:
531 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000532 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533 "msgType": msg.Header.Type, "device-id": dh.deviceID})
534 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000535 }
536 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000537}
538
mpagenkodff5dda2020-08-28 11:52:01 +0000539//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530540func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000541 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
mpagenko01e726e2020-10-23 09:45:29 +0000542 logger.Debugw("FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000543
mpagenko01e726e2020-10-23 09:45:29 +0000544 var retError error = nil
545 //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 +0000546 if apOfFlowChanges.ToRemove != nil {
547 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000548 if flowItem.GetCookie() == 0 {
mpagenko01e726e2020-10-23 09:45:29 +0000549 logger.Warnw("flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
550 "device-id": dh.deviceID})
551 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000552 continue
553 }
554 flowInPort := flow.GetInPort(flowItem)
555 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
mpagenko01e726e2020-10-23 09:45:29 +0000556 logger.Warnw("flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
557 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
558 continue
559 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000560 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000561 //this is some downstream flow, not regarded as error, just ignored
562 logger.Debugw("flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
563 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000564 continue
565 } else {
566 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530567 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000568 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
569 loUniPort = uniPort
570 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000571 logger.Warnw("flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
572 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
573 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
574 flowInPort, dh.deviceID)
575 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000576 }
577 flowOutPort := flow.GetOutPort(flowItem)
mpagenko01e726e2020-10-23 09:45:29 +0000578 logger.Debugw("flow-remove port indications", log.Fields{
579 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000580 "uniPortName": loUniPort.name})
mpagenko01e726e2020-10-23 09:45:29 +0000581 err := dh.removeFlowItemFromUniPort(flowItem, loUniPort)
582 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000583 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000584 logger.Warnw("flow-remove processing error: continuing on checking further flows",
585 log.Fields{"device-id": dh.deviceID, "error": err})
586 retError = err
587 continue
588 //return err
589 } else { // if last setting succeeds, overwrite possibly previously set error
590 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000591 }
592 }
593 }
594 }
mpagenko01e726e2020-10-23 09:45:29 +0000595 if apOfFlowChanges.ToAdd != nil {
596 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
597 if flowItem.GetCookie() == 0 {
598 logger.Debugw("incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
599 "device-id": dh.deviceID})
600 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
601 continue
602 }
603 flowInPort := flow.GetInPort(flowItem)
604 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
605 logger.Warnw("flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
606 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
607 continue
608 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
609 } else if flowInPort == dh.ponPortNumber {
610 //this is some downstream flow
611 logger.Debugw("flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
612 "device-id": dh.deviceID, "inPort": flowInPort})
613 continue
614 } else {
615 // this is the relevant upstream flow
616 var loUniPort *onuUniPort
617 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
618 loUniPort = uniPort
619 } else {
620 logger.Warnw("flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
621 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
622 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
623 flowInPort, dh.deviceID)
624 continue
625 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
626 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000627 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
628 // if not, we just throw some error here to have an indication about that, if we really need to support that
629 // then we would need to create some means to activate the internal stored flows
630 // after the device gets active automatically (and still with its dependency to the TechProfile)
631 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
632 // also abort for the other still possible flows here
633 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000634 logger.Errorw("flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000635 "last device-reason": dh.deviceReason})
636 return fmt.Errorf("improper device state on device %s", dh.deviceID)
637 }
638
mpagenko01e726e2020-10-23 09:45:29 +0000639 flowOutPort := flow.GetOutPort(flowItem)
640 logger.Debugw("flow-add port indications", log.Fields{
641 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
642 "uniPortName": loUniPort.name})
643 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
644 //try next flow after processing error
645 if err != nil {
646 logger.Warnw("flow-add processing error: continuing on checking further flows",
647 log.Fields{"device-id": dh.deviceID, "error": err})
648 retError = err
649 continue
650 //return err
651 } else { // if last setting succeeds, overwrite possibly previously set error
652 retError = nil
653 }
654 }
655 }
656 }
657 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000658}
659
Himani Chawla6d2ae152020-09-02 13:11:20 +0530660//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000661//following are the expected device states after this activity:
662//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
663// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530664func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000665 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000666
mpagenko900ee4b2020-10-12 11:56:34 +0000667 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000668 //note that disableDevice sequences in some 'ONU active' state may yield also
669 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000670 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000671 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 //disable-device shall be just a UNi/ONU-G related admin state setting
673 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000674
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000676 // disable UNI ports/ONU
677 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
678 if dh.pLockStateFsm == nil {
679 dh.createUniLockFsm(true, UniDisableStateDone)
680 } else { //LockStateFSM already init
681 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
682 dh.runUniLockFsm(true)
683 }
684 } else {
685 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
686 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
687 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
688 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
689 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
690 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
691 }
mpagenko01e726e2020-10-23 09:45:29 +0000692 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000693
694 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
695 _ = dh.deviceReasonUpdate(drOmciAdminLock, false)
mpagenko3af1f032020-06-10 08:53:41 +0000696 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300697 }
698}
699
Himani Chawla6d2ae152020-09-02 13:11:20 +0530700//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530701func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000702 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000703
mpagenkofc4f56e2020-11-04 17:17:49 +0000704 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
705 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
706 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
707 // for real ONU's that should have nearly no influence
708 // Note that for real ONU's there is anyway a problematic situation with following sequence:
709 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
710 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
711 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
712 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
713
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000714 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000715 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000716 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000717 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000718 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000719 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000720 dh.runUniLockFsm(false)
721 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300722}
723
Himani Chawla6d2ae152020-09-02 13:11:20 +0530724func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000725 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
726
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000727 pDevEntry := dh.getOnuDeviceEntry(true)
728 if pDevEntry == nil {
729 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
730 return
731 }
732 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000733 if err == fmt.Errorf("no-ONU-data-found") {
734 logger.Debugw("no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
735 } else {
736 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
737 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000738 dh.reconciling = false
739 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000740 }
Himani Chawla4d908332020-08-31 12:30:20 +0530741 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000742 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
743 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
744 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
745 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530746 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000747}
748
Himani Chawla6d2ae152020-09-02 13:11:20 +0530749func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000750 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
751
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000752 pDevEntry := dh.getOnuDeviceEntry(true)
753 if pDevEntry == nil {
754 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
755 return
756 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000757
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000758 dh.pOnuTP.lockTpProcMutex()
759 defer dh.pOnuTP.unlockTpProcMutex()
760
761 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800762 for tpID := range uniData.PersTpPathMap {
763 // deadline context to ensure completion of background routines waited for
764 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
765 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
766 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000767
Girish Gowdra041dcb32020-11-16 16:54:30 -0800768 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
769 var wg sync.WaitGroup
770 wg.Add(1) // for the 1 go routine to finish
771 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
772 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
773 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
774 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
775 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000776 }
777 }
778}
779
780func (dh *deviceHandler) reconcileDeviceFlowConfig() {
781 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
782
783 pDevEntry := dh.getOnuDeviceEntry(true)
784 if pDevEntry == nil {
785 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000786 return
787 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000788 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
789 var uniPort *onuUniPort
790 var exist bool
791 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
792 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000793 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 return
795 }
796 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000797 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
798 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000799 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000800 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
801 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
802 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
804 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000805 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000806 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
807 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000808 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
810 }
811 }
812 }
813 }
814}
815
816func (dh *deviceHandler) reconcileMetrics() {
817 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
818
819 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000820 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000821}
822
mpagenko2418ab02020-11-12 12:58:06 +0000823func (dh *deviceHandler) deleteDevicePersistencyData() error {
824 logger.Debugw("delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825
mpagenko2418ab02020-11-12 12:58:06 +0000826 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000828 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
829 logger.Debugw("OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
830 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000831 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000832 pDevEntry.lockOnuKVStoreMutex()
833 defer pDevEntry.unlockOnuKVStoreMutex()
834
835 // deadline context to ensure completion of background routines waited for
836 //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 +0530837 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 dctx, cancel := context.WithDeadline(context.Background(), deadline)
839
840 pDevEntry.resetKvProcessingErrorIndication()
841
842 var wg sync.WaitGroup
843 wg.Add(1) // for the 1 go routine to finish
844 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000845 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000846
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000847 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000849}
850
Himani Chawla6d2ae152020-09-02 13:11:20 +0530851func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000852 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300853 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000854 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300856 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530857 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530858 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
859 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
860 return err
861 }
mpagenko01e726e2020-10-23 09:45:29 +0000862
863 //transfer the possibly modified logical uni port state
864 dh.disableUniPortStateUpdate()
865
Andrea Campanellabef4e542020-10-22 11:01:28 +0200866 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000867 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200868 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300869 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000870 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000871 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300872 return err
873 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000874 if err := dh.deviceReasonUpdate(drRebooting, false); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300875 return err
876 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000877 dh.ReadyForSpecificOmciConfig = false
ozgecanetsiae11479f2020-07-06 09:44:47 +0300878 return nil
879}
880
Himani Chawla6d2ae152020-09-02 13:11:20 +0530881// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000882// #####################################################################################
883
884// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530885// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000886
Himani Chawla6d2ae152020-09-02 13:11:20 +0530887func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000888 logger.Debugw("Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
889}
890
891// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530892func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000893
894 logger.Debug("doStateInit-started")
895 var err error
896
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000897 // populate what we know. rest comes later after mib sync
898 dh.device.Root = false
899 dh.device.Vendor = "OpenONU"
900 dh.device.Model = "go"
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000901 dh.device.Reason = drActivatingOnu
902 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000903
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000904 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000905
906 if !dh.reconciling {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000907 logger.Infow("DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530908 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000909 } else {
910 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
911 log.Fields{"device-id": dh.deviceID})
912 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000913
Himani Chawla4d908332020-08-31 12:30:20 +0530914 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000915 dh.ponPortNumber = dh.device.ParentPortNo
916
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000917 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
918 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
919 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000920 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000921 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530922 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000923
924 /*
925 self._pon = PonPort.create(self, self._pon_port_number)
926 self._pon.add_peer(self.parent_id, self._pon_port_number)
927 self.logger.debug('adding-pon-port-to-agent',
928 type=self._pon.get_port().type,
929 admin_state=self._pon.get_port().admin_state,
930 oper_status=self._pon.get_port().oper_status,
931 )
932 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000933 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000934 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000935 var ponPortNo uint32 = 1
936 if dh.ponPortNumber != 0 {
937 ponPortNo = dh.ponPortNumber
938 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000939
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000940 pPonPort := &voltha.Port{
941 PortNo: ponPortNo,
942 Label: fmt.Sprintf("pon-%d", ponPortNo),
943 Type: voltha.Port_PON_ONU,
944 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530945 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000946 PortNo: ponPortNo}}, // Peer port is parent's port number
947 }
948 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
949 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
950 e.Cancel(err)
951 return
952 }
953 } else {
954 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000955 }
956 logger.Debug("doStateInit-done")
957}
958
959// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530960func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000961
962 logger.Debug("postInit-started")
963 var err error
964 /*
965 dh.Client = oop.NewOpenoltClient(dh.clientCon)
966 dh.pTransitionMap.Handle(ctx, GrpcConnected)
967 return nil
968 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530969 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
970 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000971 e.Cancel(err)
972 return
973 }
974
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000975 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530976 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000977 // reconcilement will be continued after mib download is done
978 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000979 /*
980 ############################################################################
981 # Setup Alarm handler
982 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
983 device.serial_number)
984 ############################################################################
985 # Setup PM configuration for this device
986 # Pass in ONU specific options
987 kwargs = {
988 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
989 'heartbeat': self.heartbeat,
990 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
991 }
992 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
993 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
994 self.logical_device_id, device.serial_number,
995 grouped=True, freq_override=False, **kwargs)
996 pm_config = self._pm_metrics.make_proto()
997 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
998 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
999 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1000
1001 # Note, ONU ID and UNI intf set in add_uni_port method
1002 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1003 ani_ports=[self._pon])
1004
1005 # Code to Run OMCI Test Action
1006 kwargs_omci_test_action = {
1007 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1008 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1009 }
1010 serial_number = device.serial_number
1011 self._test_request = OmciTestRequest(self.core_proxy,
1012 self.omci_agent, self.device_id,
1013 AniG, serial_number,
1014 self.logical_device_id,
1015 exclusive=False,
1016 **kwargs_omci_test_action)
1017
1018 self.enabled = True
1019 else:
1020 self.logger.info('onu-already-activated')
1021 */
1022 logger.Debug("postInit-done")
1023}
1024
1025// doStateConnected get the device info and update to voltha core
1026// for comparison of the original method (not that easy to uncomment): compare here:
1027// voltha-openolt-adapter/adaptercore/device_handler.go
1028// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +05301029func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001030
1031 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301032 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001033 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001034 logger.Debug("doStateConnected-done")
1035}
1036
1037// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301038func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001039
1040 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301041 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001042 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001043 logger.Debug("doStateUp-done")
1044
1045 /*
1046 // Synchronous call to update device state - this method is run in its own go routine
1047 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1048 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001049 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 +00001050 return err
1051 }
1052 return nil
1053 */
1054}
1055
1056// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301057func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001058
1059 logger.Debug("doStateDown-started")
1060 var err error
1061
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001062 device := dh.device
1063 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001064 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001065 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001066 e.Cancel(err)
1067 return
1068 }
1069
1070 cloned := proto.Clone(device).(*voltha.Device)
1071 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1072 /*
1073 // Update the all ports state on that device to disable
1074 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001075 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001076 return er
1077 }
1078
1079 //Update the device oper state and connection status
1080 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1081 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1082 dh.device = cloned
1083
1084 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001085 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001086 return er
1087 }
1088
1089 //get the child device for the parent device
1090 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1091 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001092 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001093 return err
1094 }
1095 for _, onuDevice := range onuDevices.Items {
1096
1097 // Update onu state as down in onu adapter
1098 onuInd := oop.OnuIndication{}
1099 onuInd.OperState = "down"
1100 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1101 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1102 if er != nil {
1103 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001104 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001105 //Do not return here and continue to process other ONUs
1106 }
1107 }
1108 // * Discovered ONUs entries need to be cleared , since after OLT
1109 // is up, it starts sending discovery indications again* /
1110 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001111 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001112 return nil
1113 */
Himani Chawla4d908332020-08-31 12:30:20 +05301114 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001117}
1118
Himani Chawla6d2ae152020-09-02 13:11:20 +05301119// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001120// #################################################################################
1121
1122// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301123// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001125//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301126func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001127 dh.lockDevice.RLock()
1128 pOnuDeviceEntry := dh.pOnuOmciDevice
1129 if aWait && pOnuDeviceEntry == nil {
1130 //keep the read sema short to allow for subsequent write
1131 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001132 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001133 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1134 // so it might be needed to wait here for that event with some timeout
1135 select {
1136 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001137 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001138 return nil
1139 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001140 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001141 // if written now, we can return the written value without sema
1142 return dh.pOnuOmciDevice
1143 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 }
mpagenko3af1f032020-06-10 08:53:41 +00001145 dh.lockDevice.RUnlock()
1146 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147}
1148
Himani Chawla6d2ae152020-09-02 13:11:20 +05301149//setOnuDeviceEntry sets the ONU device entry within the handler
1150func (dh *deviceHandler) setOnuDeviceEntry(
1151 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001152 dh.lockDevice.Lock()
1153 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001154 dh.pOnuOmciDevice = apDeviceEntry
1155 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001156}
1157
Himani Chawla6d2ae152020-09-02 13:11:20 +05301158//addOnuDeviceEntry creates a new ONU device or returns the existing
1159func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001160 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001161
Himani Chawla6d2ae152020-09-02 13:11:20 +05301162 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001163 if deviceEntry == nil {
1164 /* costum_me_map in python code seems always to be None,
1165 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1166 /* also no 'clock' argument - usage open ...*/
1167 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001168 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001169 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001170 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301171 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001172 // fire deviceEntry ready event to spread to possibly waiting processing
1173 dh.deviceEntrySet <- true
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001174 logger.Debugw("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001175 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001176 logger.Debugw("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001177 }
1178 // might be updated with some error handling !!!
1179 return nil
1180}
1181
1182// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301183func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001184 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1185 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1186
1187 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001188
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001189 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001190 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1191 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001192 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1193 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1194 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1195 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1196 }
1197 } else {
1198 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1199 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001200 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001201 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1202 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1203 // 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 +00001204 // 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 +00001205 // so let's just try to keep it simple ...
1206 /*
1207 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1208 if err != nil || device == nil {
1209 //TODO: needs to handle error scenarios
1210 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1211 return errors.New("Voltha Device not found")
1212 }
1213 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001214
Himani Chawla6d2ae152020-09-02 13:11:20 +05301215 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001216 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301217 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301218 return err
1219 }
mpagenko3af1f032020-06-10 08:53:41 +00001220 } else {
divyadesai4d299552020-08-18 07:13:49 +00001221 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001222 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001223 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001224 _ = dh.deviceReasonUpdate(drStartingOpenomci, dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001225
1226 /* this might be a good time for Omci Verify message? */
1227 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301228 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001229 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001230 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301231 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001232
1233 /* give the handler some time here to wait for the OMCi verification result
1234 after Timeout start and try MibUpload FSM anyway
1235 (to prevent stopping on just not supported OMCI verification from ONU) */
1236 select {
1237 case <-time.After(2 * time.Second):
1238 logger.Warn("omci start-verification timed out (continue normal)")
1239 case testresult := <-verifyExec:
1240 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1241 }
1242
1243 /* In py code it looks earlier (on activate ..)
1244 # Code to Run OMCI Test Action
1245 kwargs_omci_test_action = {
1246 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1247 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1248 }
1249 serial_number = device.serial_number
1250 self._test_request = OmciTestRequest(self.core_proxy,
1251 self.omci_agent, self.device_id,
1252 AniG, serial_number,
1253 self.logical_device_id,
1254 exclusive=False,
1255 **kwargs_omci_test_action)
1256 ...
1257 # Start test requests after a brief pause
1258 if not self._test_request_started:
1259 self._test_request_started = True
1260 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1261 reactor.callLater(tststart, self._test_request.start_collector)
1262
1263 */
1264 /* which is then: in omci_test_request.py : */
1265 /*
1266 def start_collector(self, callback=None):
1267 """
1268 Start the collection loop for an adapter if the frequency > 0
1269
1270 :param callback: (callable) Function to call to collect PM data
1271 """
1272 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1273 if callback is None:
1274 callback = self.perform_test_omci
1275
1276 if self.lc is None:
1277 self.lc = LoopingCall(callback)
1278
1279 if self.default_freq > 0:
1280 self.lc.start(interval=self.default_freq / 10)
1281
1282 def perform_test_omci(self):
1283 """
1284 Perform the initial test request
1285 """
1286 ani_g_entities = self._device.configuration.ani_g_entities
1287 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1288 is not None else None
1289 self._entity_id = ani_g_entities_ids[0]
1290 self.logger.info('perform-test', entity_class=self._entity_class,
1291 entity_id=self._entity_id)
1292 try:
1293 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1294 result = yield self._device.omci_cc.send(frame)
1295 if not result.fields['omci_message'].fields['success_code']:
1296 self.logger.info('Self-Test Submitted Successfully',
1297 code=result.fields[
1298 'omci_message'].fields['success_code'])
1299 else:
1300 raise TestFailure('Test Failure: {}'.format(
1301 result.fields['omci_message'].fields['success_code']))
1302 except TimeoutError as e:
1303 self.deferred.errback(failure.Failure(e))
1304
1305 except Exception as e:
1306 self.logger.exception('perform-test-Error', e=e,
1307 class_id=self._entity_class,
1308 entity_id=self._entity_id)
1309 self.deferred.errback(failure.Failure(e))
1310
1311 */
1312
1313 // PM related heartbeat??? !!!TODO....
1314 //self._heartbeat.enabled = True
1315
mpagenko1cc3cb42020-07-27 15:24:38 +00001316 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1317 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1318 * 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 +05301319 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001320 */
1321 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001322 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001323 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001324 if pMibUlFsm.Is(ulStDisabled) {
1325 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001326 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001327 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301328 }
1329 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1330 //Determine ONU status and start/re-start MIB Synchronization tasks
1331 //Determine if this ONU has ever synchronized
1332 if true { //TODO: insert valid check
1333 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001334 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001335 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001336 }
Himani Chawla4d908332020-08-31 12:30:20 +05301337 } else {
1338 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001339 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001340 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301341 }
1342 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1343 //Examine the MIB Data Sync
1344 // callbacks to be handled:
1345 // Event(ulEvSuccess)
1346 // Event(ulEvTimeout)
1347 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001348 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001349 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001350 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001351 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001352 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001353 }
1354 } else {
divyadesai4d299552020-08-18 07:13:49 +00001355 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001356 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001357 }
1358 return nil
1359}
1360
Himani Chawla6d2ae152020-09-02 13:11:20 +05301361func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001362 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001363 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001364 if dh.deviceReason != drStoppingOpenomci {
divyadesai4d299552020-08-18 07:13:49 +00001365 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001366
mpagenko900ee4b2020-10-12 11:56:34 +00001367 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1368 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1369 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1370 if err := dh.resetFsms(); err != nil {
1371 logger.Errorw("error-updateInterface at FSM stop",
1372 log.Fields{"device-id": dh.deviceID, "error": err})
1373 // abort: system behavior is just unstable ...
1374 return err
1375 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001376 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
mpagenko2418ab02020-11-12 12:58:06 +00001377 _ = dh.deleteDevicePersistencyData() //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001378
1379 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1380 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1381 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301382 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001383 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001384 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001385 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001386 }
mpagenko900ee4b2020-10-12 11:56:34 +00001387 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001388
1389 //TODO!!! remove existing traffic profiles
1390 /* from py code, if TP's exist, remove them - not yet implemented
1391 self._tp = dict()
1392 # Let TP download happen again
1393 for uni_id in self._tp_service_specific_task:
1394 self._tp_service_specific_task[uni_id].clear()
1395 for uni_id in self._tech_profile_download_done:
1396 self._tech_profile_download_done[uni_id].clear()
1397 */
1398
1399 dh.disableUniPortStateUpdate()
1400
mpagenkofc4f56e2020-11-04 17:17:49 +00001401 dh.ReadyForSpecificOmciConfig = false
1402
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001403 if err := dh.deviceReasonUpdate(drStoppingOpenomci, false); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001404 // abort: system behavior is just unstable ...
1405 return err
1406 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001407 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1408 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001409 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1410 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001411 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001412 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001413 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001414 // abort: system behavior is just unstable ...
1415 return err
1416 }
1417 } else {
divyadesai4d299552020-08-18 07:13:49 +00001418 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001419 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001420 return nil
1421}
1422
mpagenko900ee4b2020-10-12 11:56:34 +00001423func (dh *deviceHandler) resetFsms() error {
1424 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1425 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1426 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1427 // and using the stop/reset event should never harm
1428
1429 pDevEntry := dh.getOnuDeviceEntry(false)
1430 if pDevEntry == nil {
1431 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1432 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1433 }
1434
1435 //the MibSync FSM might be active all the ONU-active time,
1436 // hence it must be stopped unconditionally
1437 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1438 if pMibUlFsm != nil {
1439 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1440 }
1441 //MibDownload may run
1442 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1443 if pMibDlFsm != nil {
1444 _ = pMibDlFsm.Event(dlEvReset)
1445 }
1446 //port lock/unlock FSM's may be active
1447 if dh.pUnlockStateFsm != nil {
1448 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1449 }
1450 if dh.pLockStateFsm != nil {
1451 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1452 }
1453 //techProfile related PonAniConfigFsm FSM may be active
1454 if dh.pOnuTP != nil {
1455 // should always be the case here
1456 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1457 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001458 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1459 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1460 }
mpagenko900ee4b2020-10-12 11:56:34 +00001461 }
1462 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001463 // reset the possibly existing VlanConfigFsm
1464 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1465 //VlanFilterFsm exists and was already started
1466 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1467 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001468 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001469 // no need to remove specific data
1470 pVlanFilterFsm.RequestClearPersistency(false)
1471 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001472 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1473 }
1474 }
1475 }
1476 }
1477 //TODO!!! care about PM/Alarm processing once started
1478 return nil
1479}
1480
Himani Chawla6d2ae152020-09-02 13:11:20 +05301481func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001482 logger.Debugw("MibInSync event received, adding uni ports and locking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301483
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001484 _ = dh.deviceReasonUpdate(drDiscoveryMibsyncComplete, dh.reconciling)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301485 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenkoa40e99a2020-11-17 13:50:39 +00001486 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301487 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301488 for _, mgmtEntityID := range unigInstKeys {
1489 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1490 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301491 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301492 i++
1493 }
1494 } else {
1495 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1496 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301497 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301498 for _, mgmtEntityID := range veipInstKeys {
1499 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1500 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301501 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301502 i++
1503 }
1504 } else {
1505 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1506 }
1507 if i == 0 {
1508 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1509 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001510 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1511 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1512 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1513 * disable/enable toggling here to allow traffic
1514 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1515 * like the py comment says:
1516 * # start by locking all the unis till mib sync and initial mib is downloaded
1517 * # this way we can capture the port down/up events when we are ready
1518 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301519
mpagenkoa40e99a2020-11-17 13:50:39 +00001520 // Init Uni Ports to Admin locked state
1521 // *** should generate UniLockStateDone event *****
1522 if dh.pLockStateFsm == nil {
1523 dh.createUniLockFsm(true, UniLockStateDone)
1524 } else { //LockStateFSM already init
1525 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
1526 dh.runUniLockFsm(true)
1527 }
1528}
1529
1530func (dh *deviceHandler) processUniLockStateDoneEvent(devEvent OnuDeviceEvent) {
1531 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301532 /* Mib download procedure -
1533 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1534 */
mpagenkoa40e99a2020-11-17 13:50:39 +00001535 pDevEntry := dh.getOnuDeviceEntry(false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301536 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1537 if pMibDlFsm != nil {
1538 if pMibDlFsm.Is(dlStDisabled) {
1539 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001540 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301541 // maybe try a FSM reset and then again ... - TODO!!!
1542 } else {
1543 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1544 // maybe use more specific states here for the specific download steps ...
1545 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001546 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301547 } else {
1548 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1549 //Begin MIB data download (running autonomously)
1550 }
1551 }
1552 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001553 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001554 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301555 // maybe try a FSM reset and then again ... - TODO!!!
1556 }
1557 /***** Mib download started */
1558 } else {
1559 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1560 }
1561}
1562
Himani Chawla6d2ae152020-09-02 13:11:20 +05301563func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001564 logger.Debugw("MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301565 //initiate DevStateUpdate
1566 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001567 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1568 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301569 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1570 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1571 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1572 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1573 } else {
1574 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1575 }
1576 } else {
1577 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1578 log.Fields{"device-id": dh.deviceID})
1579 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001580 _ = dh.deviceReasonUpdate(drInitialMibDownloaded, dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001581 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301582 // *** should generate UniUnlockStateDone event *****
1583 if dh.pUnlockStateFsm == nil {
1584 dh.createUniLockFsm(false, UniUnlockStateDone)
1585 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301586 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301587 dh.runUniLockFsm(false)
1588 }
1589}
1590
Himani Chawla6d2ae152020-09-02 13:11:20 +05301591func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001592 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301593
1594 if !dh.reconciling {
1595 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1596 raisedTs := time.Now().UnixNano()
1597 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1598 } else {
1599 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1600 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301601 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001602 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301603 }
1604}
1605
mpagenko900ee4b2020-10-12 11:56:34 +00001606func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1607 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1608 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1609 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1610 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1611 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1612 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1613 }
1614
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001615 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{"reason": drOmciAdminLock, "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001616 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001617 _ = dh.deviceReasonUpdate(drOmciAdminLock, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001618
1619 //transfer the modified logical uni port state
1620 dh.disableUniPortStateUpdate()
mpagenko900ee4b2020-10-12 11:56:34 +00001621}
1622
1623func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1624 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1625 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1626 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1627 voltha.OperStatus_ACTIVE); err != nil {
1628 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1629 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1630 }
1631
1632 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001633 "reason": drOnuReenabled, "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001634 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001635 _ = dh.deviceReasonUpdate(drOnuReenabled, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001636
1637 //transfer the modified logical uni port state
1638 dh.enableUniPortStateUpdate()
1639}
1640
Himani Chawla6d2ae152020-09-02 13:11:20 +05301641func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001642 if devEvent == OmciAniConfigDone {
1643 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1644 // attention: the device reason update is done based on ONU-UNI-Port related activity
1645 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001646 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001647 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001648 _ = dh.deviceReasonUpdate(drTechProfileConfigDownloadSuccess, dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301649 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001650 if dh.reconciling {
1651 go dh.reconcileDeviceFlowConfig()
1652 }
1653 } else { // should be the OmciAniResourceRemoved block
1654 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1655 // attention: the device reason update is done based on ONU-UNI-Port related activity
1656 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001657 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001658 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001659 _ = dh.deviceReasonUpdate(drTechProfileConfigDeleteSuccess, false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001660 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001661 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301662}
1663
mpagenkofc4f56e2020-11-04 17:17:49 +00001664func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301665 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001666 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301667 // attention: the device reason update is done based on ONU-UNI-Port related activity
1668 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301669
mpagenkofc4f56e2020-11-04 17:17:49 +00001670 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001671 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001672 // which may be the case from some previous actvity on another UNI Port of the ONU
1673 // or even some previous flow add activity on the same port
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001674 _ = dh.deviceReasonUpdate(drOmciFlowsPushed, dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001675 if dh.reconciling {
1676 go dh.reconcileMetrics()
1677 }
1678 }
1679 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001680 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001681 //not relevant for reconcile
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001682 _ = dh.deviceReasonUpdate(drOmciFlowsDeleted, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001683 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301684 }
1685}
1686
Himani Chawla6d2ae152020-09-02 13:11:20 +05301687//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1688func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301689 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001690 case MibDatabaseSync:
1691 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301692 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001693 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001694 case UniLockStateDone:
1695 {
1696 dh.processUniLockStateDoneEvent(devEvent)
1697 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001698 case MibDownloadDone:
1699 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301700 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001701 }
1702 case UniUnlockStateDone:
1703 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301704 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001705 }
mpagenko900ee4b2020-10-12 11:56:34 +00001706 case UniEnableStateDone:
1707 {
1708 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001709 }
1710 case UniDisableStateDone:
1711 {
1712 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001713 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001714 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001715 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301716 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001717 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001718 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001719 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301720 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001721 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001722 default:
1723 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001724 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001725 }
1726 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001727}
1728
Himani Chawla6d2ae152020-09-02 13:11:20 +05301729func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001730 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301731 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301732 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001733 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301734 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301736 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301737 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001738 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301739 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001741 //store UniPort with the System-PortNumber key
1742 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001743 if !dh.reconciling {
1744 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301745 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001746 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1747 } //error logging already within UniPort method
1748 } else {
1749 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1750 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001751 }
1752 }
1753}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001754
mpagenko3af1f032020-06-10 08:53:41 +00001755// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301756func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001757 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301758 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001759 // with following remark:
1760 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1761 // # load on the core
1762
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001763 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001764
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001765 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001766 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301767 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001768 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301769 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001770 if !dh.reconciling {
1771 //maybe also use getter functions on uniPort - perhaps later ...
1772 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1773 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001774 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001775 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1776 }
mpagenko3af1f032020-06-10 08:53:41 +00001777 }
1778 }
1779}
1780
1781// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301782func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001783 // compare enableUniPortStateUpdate() above
1784 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1785 for uniNo, uniPort := range dh.uniEntityMap {
1786 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301787 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001788 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301789 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001790 //maybe also use getter functions on uniPort - perhaps later ...
1791 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001792 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001793 }
1794}
1795
1796// ONU_Active/Inactive announcement on system KAFKA bus
1797// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301798func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001799 var de voltha.DeviceEvent
1800 eventContext := make(map[string]string)
1801 //Populating event context
1802 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301803 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001804 if err != nil || parentDevice == nil {
1805 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301806 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001807 }
1808 oltSerialNumber := parentDevice.SerialNumber
1809
1810 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1811 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1812 eventContext["serial-number"] = dh.device.SerialNumber
1813 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301814 eventContext["device_id"] = aDeviceID
1815 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001816 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001817 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001818
1819 /* Populating device event body */
1820 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301821 de.ResourceId = aDeviceID
1822 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001823 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1824 de.Description = fmt.Sprintf("%s Event - %s - %s",
1825 cEventObjectType, cOnuActivatedEvent, "Raised")
1826 } else {
1827 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1828 de.Description = fmt.Sprintf("%s Event - %s - %s",
1829 cEventObjectType, cOnuActivatedEvent, "Cleared")
1830 }
1831 /* Send event to KAFKA */
1832 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1833 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301834 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001835 }
1836 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301837 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001838}
1839
Himani Chawla4d908332020-08-31 12:30:20 +05301840// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301841func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001842 chLSFsm := make(chan Message, 2048)
1843 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301844 if aAdminState {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001845 logger.Debugw("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001846 sFsmName = "LockStateFSM"
1847 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001848 logger.Debugw("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001849 sFsmName = "UnLockStateFSM"
1850 }
mpagenko3af1f032020-06-10 08:53:41 +00001851
Himani Chawla6d2ae152020-09-02 13:11:20 +05301852 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001853 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001854 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001855 return
1856 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301857 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001858 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001859 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301860 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001861 dh.pLockStateFsm = pLSFsm
1862 } else {
1863 dh.pUnlockStateFsm = pLSFsm
1864 }
1865 dh.runUniLockFsm(aAdminState)
1866 } else {
divyadesai4d299552020-08-18 07:13:49 +00001867 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001868 }
1869}
1870
1871// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301872func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001873 /* Uni Port lock/unlock procedure -
1874 ***** should run via 'adminDone' state and generate the argument requested event *****
1875 */
1876 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301877 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001878 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1879 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1880 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001881 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301882 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001883 }
1884 } else {
1885 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1886 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1887 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001888 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301889 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001890 }
1891 }
1892 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001893 if pLSStatemachine.Is(uniStDisabled) {
1894 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001895 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1896 // maybe try a FSM reset and then again ... - TODO!!!
1897 } else {
1898 /***** LockStateFSM started */
1899 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001900 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001901 }
1902 } else {
1903 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001904 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001905 // maybe try a FSM reset and then again ... - TODO!!!
1906 }
1907 } else {
divyadesai4d299552020-08-18 07:13:49 +00001908 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001909 // maybe try a FSM reset and then again ... - TODO!!!
1910 }
1911}
1912
Himani Chawla6d2ae152020-09-02 13:11:20 +05301913//setBackend provides a DB backend for the specified path on the existing KV client
1914func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001915 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1916 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001917 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001918 kvbackend := &db.Backend{
1919 Client: dh.pOpenOnuAc.kvClient,
1920 StoreType: dh.pOpenOnuAc.KVStoreType,
1921 /* address config update acc. to [VOL-2736] */
1922 Address: addr,
1923 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1924 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001925
mpagenkoaf801632020-07-03 10:00:42 +00001926 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001927}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301928func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301929 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001930
mpagenkodff5dda2020-08-28 11:52:01 +00001931 for _, field := range flow.GetOfbFields(apFlowItem) {
1932 switch field.Type {
1933 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1934 {
mpagenko01e726e2020-10-23 09:45:29 +00001935 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001936 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1937 }
mpagenko01e726e2020-10-23 09:45:29 +00001938 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00001939 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1940 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301941 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00001942 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301943 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1944 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001945 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1946 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00001947 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
1948 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301949 return
mpagenkodff5dda2020-08-28 11:52:01 +00001950 }
1951 }
mpagenko01e726e2020-10-23 09:45:29 +00001952 */
mpagenkodff5dda2020-08-28 11:52:01 +00001953 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1954 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301955 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001956 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301957 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001958 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301959 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001960 }
mpagenko01e726e2020-10-23 09:45:29 +00001961 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301962 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001963 }
1964 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1965 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301966 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00001967 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001968 "PCP": loAddPcp})
1969 }
1970 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1971 {
mpagenko01e726e2020-10-23 09:45:29 +00001972 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001973 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1974 }
1975 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1976 {
mpagenko01e726e2020-10-23 09:45:29 +00001977 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001978 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1979 }
1980 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1981 {
mpagenko01e726e2020-10-23 09:45:29 +00001982 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001983 "IPv4-DST": field.GetIpv4Dst()})
1984 }
1985 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1986 {
mpagenko01e726e2020-10-23 09:45:29 +00001987 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001988 "IPv4-SRC": field.GetIpv4Src()})
1989 }
1990 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1991 {
mpagenko01e726e2020-10-23 09:45:29 +00001992 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001993 "Metadata": field.GetTableMetadata()})
1994 }
1995 /*
1996 default:
1997 {
1998 //all other entires ignored
1999 }
2000 */
2001 }
2002 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302003}
mpagenkodff5dda2020-08-28 11:52:01 +00002004
Himani Chawla6d2ae152020-09-02 13:11:20 +05302005func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002006 for _, action := range flow.GetActions(apFlowItem) {
2007 switch action.Type {
2008 /* not used:
2009 case of.OfpActionType_OFPAT_OUTPUT:
2010 {
mpagenko01e726e2020-10-23 09:45:29 +00002011 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002012 "Output": action.GetOutput()})
2013 }
2014 */
2015 case of.OfpActionType_OFPAT_PUSH_VLAN:
2016 {
mpagenko01e726e2020-10-23 09:45:29 +00002017 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002018 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2019 }
2020 case of.OfpActionType_OFPAT_SET_FIELD:
2021 {
2022 pActionSetField := action.GetSetField()
2023 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00002024 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002025 "OxcmClass": pActionSetField.Field.OxmClass})
2026 }
2027 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302028 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002029 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302030 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002031 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302032 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002033 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302034 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002035 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002036 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002037 "Type": pActionSetField.Field.GetOfbField().Type})
2038 }
2039 }
2040 /*
2041 default:
2042 {
2043 //all other entires ignored
2044 }
2045 */
2046 }
2047 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302048}
2049
2050//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302051func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302052 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2053 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2054 var loAddPcp, loSetPcp uint8
2055 var loIPProto uint32
2056 /* the TechProfileId is part of the flow Metadata - compare also comment within
2057 * OLT-Adapter:openolt_flowmgr.go
2058 * Metadata 8 bytes:
2059 * Most Significant 2 Bytes = Inner VLAN
2060 * Next 2 Bytes = Tech Profile ID(TPID)
2061 * Least Significant 4 Bytes = Port ID
2062 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2063 * subscriber related flows.
2064 */
2065
2066 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2067 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002068 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302069 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002070 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302071 }
2072 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002073 loCookie := apFlowItem.GetCookie()
2074 loCookieSlice := []uint64{loCookie}
2075 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2076 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302077
2078 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002079 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302080 if loIPProto == 2 {
2081 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2082 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002083 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2084 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302085 return nil
2086 }
mpagenko01e726e2020-10-23 09:45:29 +00002087 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302088 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002089
2090 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002091 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002092 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2093 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2094 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2095 //TODO!!: Use DeviceId within the error response to rwCore
2096 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002097 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002098 }
2099 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002100 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002101 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2102 } else {
2103 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2104 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2105 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302106 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002107 }
mpagenko01e726e2020-10-23 09:45:29 +00002108 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002109 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302110 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002111 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2112 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002113 }
mpagenko01e726e2020-10-23 09:45:29 +00002114 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002115 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002116}
2117
2118//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2119func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2120 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2121 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2122 //no extra check is done on the rule parameters
2123 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2124 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2125 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2126 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002127 // - 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 +00002128 loCookie := apFlowItem.GetCookie()
2129 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2130
2131 /* TT related temporary workaround - should not be needed anymore
2132 for _, field := range flow.GetOfbFields(apFlowItem) {
2133 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2134 loIPProto := field.GetIpProto()
2135 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2136 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2137 if loIPProto == 2 {
2138 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2139 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2140 log.Fields{"device-id": dh.deviceID})
2141 return nil
2142 }
2143 }
2144 } //for all OfbFields
2145 */
2146
2147 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2148 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2149 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002150 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002151 log.Fields{"device-id": dh.deviceID})
2152 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002153 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2154 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2155
mpagenko01e726e2020-10-23 09:45:29 +00002156 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002157}
2158
Himani Chawla26e555c2020-08-31 12:30:20 +05302159// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002160func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2161 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002162 chVlanFilterFsm := make(chan Message, 2048)
2163
Himani Chawla6d2ae152020-09-02 13:11:20 +05302164 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002165 if pDevEntry == nil {
2166 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302167 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002168 }
2169
2170 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002171 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2172 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002173 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302174 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002175 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2176 if pVlanFilterStatemachine != nil {
2177 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2178 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2179 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302180 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002181 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302182 /***** UniVlanConfigFsm started */
2183 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2184 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2185 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002186 } else {
2187 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2188 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302189 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002190 }
2191 } else {
2192 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2193 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302194 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002195 }
2196 } else {
2197 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2198 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302199 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002200 }
2201 return nil
2202}
2203
mpagenkofc4f56e2020-11-04 17:17:49 +00002204//VerifyVlanConfigRequest checks on existence of a given uniPort
2205// and starts verification of flow config based on that
2206func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2207 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2208 var pCurrentUniPort *onuUniPort
2209 for _, uniPort := range dh.uniEntityMap {
2210 // only if this port is validated for operState transfer
2211 if uniPort.uniID == uint8(aUniID) {
2212 pCurrentUniPort = uniPort
2213 break //found - end search loop
2214 }
2215 }
2216 if pCurrentUniPort == nil {
2217 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2218 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2219 return
2220 }
2221 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2222}
2223
mpagenkodff5dda2020-08-28 11:52:01 +00002224//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302225func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002226 //TODO!! verify and start pending flow configuration
2227 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2228 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302229 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002230 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2231 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2232 if pVlanFilterStatemachine != nil {
2233 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2234 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2235 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2236 } else {
2237 /***** UniVlanConfigFsm continued */
2238 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2239 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2240 "UniPort": apUniPort.portNo})
2241 }
2242 } else {
2243 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2244 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2245 }
2246 } else {
2247 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2248 "device-id": dh.deviceID})
2249 }
2250
2251 } // else: nothing to do
2252}
2253
2254//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2255// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
Himani Chawla6d2ae152020-09-02 13:11:20 +05302256func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002257 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2258 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2259 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302260 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002261}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002262
2263//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2264//available for potential reconcilement
2265
2266func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2267
2268 if dh.reconciling {
2269 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2270 return nil
2271 }
mpagenko2418ab02020-11-12 12:58:06 +00002272 logger.Debugw("Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002273
2274 pDevEntry := dh.getOnuDeviceEntry(true)
2275 if pDevEntry == nil {
2276 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2277 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2278 }
2279 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2280
2281 pDevEntry.lockOnuKVStoreMutex()
2282 defer pDevEntry.unlockOnuKVStoreMutex()
2283
2284 // deadline context to ensure completion of background routines waited for
2285 //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 +05302286 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002287 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2288
2289 pDevEntry.resetKvProcessingErrorIndication()
2290 var wg sync.WaitGroup
2291 wg.Add(1) // for the 1 go routine to finish
2292
2293 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002294 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002295
2296 return pDevEntry.getKvProcessingErrorIndication()
2297}
2298
mpagenko01e726e2020-10-23 09:45:29 +00002299func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002300 defer cancel() //ensure termination of context (may be pro forma)
2301 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002302 logger.Debugw("WaitGroup processing completed", log.Fields{
2303 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002304}
2305
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002306func (dh *deviceHandler) deviceReasonUpdate(deviceReason string, dontNotifyCore bool) error {
2307
2308 dh.deviceReason = deviceReason
2309 if !dontNotifyCore {
2310 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
2311 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, deviceReason); err != nil {
2312 logger.Errorw("DeviceReasonUpdate: error",
2313 log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID, "error": err})
2314 return err
2315 }
2316 logger.Infow("DeviceReasonUpdate: success", log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID})
2317 return nil
2318 }
2319 logger.Infow("Don't notify core about DeviceReasonUpdate", log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID})
2320 return nil
2321}
2322
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002323func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2324 var errStr string = ""
2325 for _, err := range errS {
2326 if err != nil {
2327 errStr = errStr + err.Error() + " "
2328 }
2329 }
2330 if errStr != "" {
2331 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2332 }
2333 return nil
2334}