blob: fbb324e2368ca787459cd8e142cb0cd720816d44 [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) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530265 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000266
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000267 logger.Infow("tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
268
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000269 pDevEntry := dh.getOnuDeviceEntry(true)
270 if pDevEntry == nil {
271 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
272 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
273 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530274 if dh.pOnuTP == nil {
275 //should normally not happen ...
mpagenkoa40e99a2020-11-17 13:50:39 +0000276 logger.Errorw("onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530277 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000278 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530279 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000280 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000281 logger.Errorw("TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000282 "device-state": dh.deviceReason})
283 return fmt.Errorf("improper device state %s on device %s", dh.deviceReason, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530284 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000285 //previous state test here was just this one, now extended for more states to reject the SetRequest:
286 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
287 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530288
289 msgBody := msg.GetBody()
290 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
291 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
292 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
293 "device-id": dh.deviceID, "error": err})
294 return err
295 }
296
297 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000298 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
299 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530300 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000301 defer dh.pOnuTP.unlockTpProcMutex()
302 pDevEntry.lockOnuKVStoreMutex()
303 defer pDevEntry.unlockOnuKVStoreMutex()
304
305 if techProfMsg.UniId > 255 {
306 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
307 techProfMsg.UniId, dh.deviceID))
308 }
309 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800310 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
311 if err != nil {
312 logger.Errorw("error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
313 return err
314 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000315
Girish Gowdra041dcb32020-11-16 16:54:30 -0800316 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530317 // if there has been some change for some uni TechProfilePath
318 //in order to allow concurrent calls to other dh instances we do not wait for execution here
319 //but doing so we can not indicate problems to the caller (who does what with that then?)
320 //by now we just assume straightforward successful execution
321 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
322 // possible problems to the caller later autonomously
323
324 // deadline context to ensure completion of background routines waited for
325 //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 +0530326 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 dctx, cancel := context.WithDeadline(context.Background(), deadline)
328
Girish Gowdra041dcb32020-11-16 16:54:30 -0800329 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000330 pDevEntry.resetKvProcessingErrorIndication()
331
Himani Chawla26e555c2020-08-31 12:30:20 +0530332 var wg sync.WaitGroup
333 wg.Add(2) // for the 2 go routines to finish
334 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000335 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
336 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000337 dh.waitForCompletion(cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000338
Girish Gowdra041dcb32020-11-16 16:54:30 -0800339 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000341 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 return nil
343}
344
Himani Chawla6d2ae152020-09-02 13:11:20 +0530345func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 msg *ic.InterAdapterMessage) error {
347
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000348 logger.Infow("delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
349
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000350 pDevEntry := dh.getOnuDeviceEntry(true)
351 if pDevEntry == nil {
352 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
353 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
354 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 if dh.pOnuTP == nil {
356 //should normally not happen ...
357 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
358 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000359 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 }
361
362 msgBody := msg.GetBody()
363 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
364 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
365 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
366 "device-id": dh.deviceID, "error": err})
367 return err
368 }
369
370 //compare TECH_PROFILE_DOWNLOAD_REQUEST
371 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 defer dh.pOnuTP.unlockTpProcMutex()
373 pDevEntry.lockOnuKVStoreMutex()
374 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530375
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 if delGemPortMsg.UniId > 255 {
377 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
378 delGemPortMsg.UniId, dh.deviceID))
379 }
380 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800381 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
382 if err != nil {
383 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
384 return err
385 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530386
mpagenkofc4f56e2020-11-04 17:17:49 +0000387 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388
mpagenkofc4f56e2020-11-04 17:17:49 +0000389 // deadline context to ensure completion of background routines waited for
390 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
391 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392
Girish Gowdra041dcb32020-11-16 16:54:30 -0800393 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394
mpagenkofc4f56e2020-11-04 17:17:49 +0000395 var wg sync.WaitGroup
396 wg.Add(1) // for the 1 go routine to finish
397 go dh.pOnuTP.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
398 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
399 dh.waitForCompletion(cancel, &wg, "GemDelete") //wait for background process to finish
400
Girish Gowdra041dcb32020-11-16 16:54:30 -0800401 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530402}
403
Himani Chawla6d2ae152020-09-02 13:11:20 +0530404func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000407 logger.Infow("delete-tcont-request", log.Fields{"device-id": dh.deviceID})
408
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409 pDevEntry := dh.getOnuDeviceEntry(true)
410 if pDevEntry == nil {
411 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
412 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
413 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530414 if dh.pOnuTP == nil {
415 //should normally not happen ...
416 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
417 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 }
420
421 msgBody := msg.GetBody()
422 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
423 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
424 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
425 "device-id": dh.deviceID, "error": err})
426 return err
427 }
428
429 //compare TECH_PROFILE_DOWNLOAD_REQUEST
430 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000431 defer dh.pOnuTP.unlockTpProcMutex()
432 pDevEntry.lockOnuKVStoreMutex()
433 defer pDevEntry.unlockOnuKVStoreMutex()
434
435 if delTcontMsg.UniId > 255 {
436 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
437 delTcontMsg.UniId, dh.deviceID))
438 }
439 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800440 tpPath := delTcontMsg.TpPath
441 tpID, err := GetTpIDFromTpPath(tpPath)
442 if err != nil {
443 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
444 return err
445 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000446
Girish Gowdra041dcb32020-11-16 16:54:30 -0800447 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530448 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530449 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530450 dctx, cancel := context.WithDeadline(context.Background(), deadline)
451
Girish Gowdra041dcb32020-11-16 16:54:30 -0800452 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453 pDevEntry.resetKvProcessingErrorIndication()
454
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 var wg sync.WaitGroup
456 wg.Add(2) // for the 2 go routines to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000457 go dh.pOnuTP.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 cResourceTcont, delTcontMsg.AllocId, &wg)
459 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000460 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000461 dh.waitForCompletion(cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000462
Girish Gowdra041dcb32020-11-16 16:54:30 -0800463 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530464 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530465 return nil
466}
467
Himani Chawla6d2ae152020-09-02 13:11:20 +0530468//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000469// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
470// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530471func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000472 msgID := msg.Header.Id
473 msgType := msg.Header.Type
474 fromTopic := msg.Header.FromTopic
475 toTopic := msg.Header.ToTopic
476 toDeviceID := msg.Header.ToDeviceId
477 proxyDeviceID := msg.Header.ProxyDeviceId
478 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
479 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
480
481 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000482 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000483 case ic.InterAdapterMessageType_OMCI_REQUEST:
484 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000486 }
mpagenkoaf801632020-07-03 10:00:42 +0000487 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
488 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000490 }
491 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
492 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000494
mpagenkoaf801632020-07-03 10:00:42 +0000495 }
496 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
497 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530498 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000499 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000500 default:
501 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000502 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503 "msgType": msg.Header.Type, "device-id": dh.deviceID})
504 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000505 }
506 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000507}
508
mpagenkodff5dda2020-08-28 11:52:01 +0000509//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530510func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000511 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
mpagenko01e726e2020-10-23 09:45:29 +0000512 logger.Debugw("FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000513
mpagenko01e726e2020-10-23 09:45:29 +0000514 var retError error = nil
515 //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 +0000516 if apOfFlowChanges.ToRemove != nil {
517 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000518 if flowItem.GetCookie() == 0 {
mpagenko01e726e2020-10-23 09:45:29 +0000519 logger.Warnw("flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
520 "device-id": dh.deviceID})
521 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000522 continue
523 }
524 flowInPort := flow.GetInPort(flowItem)
525 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
mpagenko01e726e2020-10-23 09:45:29 +0000526 logger.Warnw("flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
527 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
528 continue
529 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000530 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000531 //this is some downstream flow, not regarded as error, just ignored
532 logger.Debugw("flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
533 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000534 continue
535 } else {
536 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530537 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000538 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
539 loUniPort = uniPort
540 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000541 logger.Warnw("flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
542 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
543 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
544 flowInPort, dh.deviceID)
545 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000546 }
547 flowOutPort := flow.GetOutPort(flowItem)
mpagenko01e726e2020-10-23 09:45:29 +0000548 logger.Debugw("flow-remove port indications", log.Fields{
549 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000550 "uniPortName": loUniPort.name})
mpagenko01e726e2020-10-23 09:45:29 +0000551 err := dh.removeFlowItemFromUniPort(flowItem, loUniPort)
552 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000553 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000554 logger.Warnw("flow-remove processing error: continuing on checking further flows",
555 log.Fields{"device-id": dh.deviceID, "error": err})
556 retError = err
557 continue
558 //return err
559 } else { // if last setting succeeds, overwrite possibly previously set error
560 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000561 }
562 }
563 }
564 }
mpagenko01e726e2020-10-23 09:45:29 +0000565 if apOfFlowChanges.ToAdd != nil {
566 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
567 if flowItem.GetCookie() == 0 {
568 logger.Debugw("incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
569 "device-id": dh.deviceID})
570 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
571 continue
572 }
573 flowInPort := flow.GetInPort(flowItem)
574 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
575 logger.Warnw("flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
576 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
577 continue
578 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
579 } else if flowInPort == dh.ponPortNumber {
580 //this is some downstream flow
581 logger.Debugw("flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
582 "device-id": dh.deviceID, "inPort": flowInPort})
583 continue
584 } else {
585 // this is the relevant upstream flow
586 var loUniPort *onuUniPort
587 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
588 loUniPort = uniPort
589 } else {
590 logger.Warnw("flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
591 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
592 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
593 flowInPort, dh.deviceID)
594 continue
595 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
596 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000597 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
598 // if not, we just throw some error here to have an indication about that, if we really need to support that
599 // then we would need to create some means to activate the internal stored flows
600 // after the device gets active automatically (and still with its dependency to the TechProfile)
601 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
602 // also abort for the other still possible flows here
603 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000604 logger.Errorw("flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000605 "last device-reason": dh.deviceReason})
606 return fmt.Errorf("improper device state on device %s", dh.deviceID)
607 }
608
mpagenko01e726e2020-10-23 09:45:29 +0000609 flowOutPort := flow.GetOutPort(flowItem)
610 logger.Debugw("flow-add port indications", log.Fields{
611 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
612 "uniPortName": loUniPort.name})
613 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
614 //try next flow after processing error
615 if err != nil {
616 logger.Warnw("flow-add processing error: continuing on checking further flows",
617 log.Fields{"device-id": dh.deviceID, "error": err})
618 retError = err
619 continue
620 //return err
621 } else { // if last setting succeeds, overwrite possibly previously set error
622 retError = nil
623 }
624 }
625 }
626 }
627 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000628}
629
Himani Chawla6d2ae152020-09-02 13:11:20 +0530630//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000631//following are the expected device states after this activity:
632//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
633// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530634func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000635 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000636
mpagenko900ee4b2020-10-12 11:56:34 +0000637 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000638 //note that disableDevice sequences in some 'ONU active' state may yield also
639 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000640 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000641 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000642 //disable-device shall be just a UNi/ONU-G related admin state setting
643 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000644
mpagenkofc4f56e2020-11-04 17:17:49 +0000645 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000646 // disable UNI ports/ONU
647 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
648 if dh.pLockStateFsm == nil {
649 dh.createUniLockFsm(true, UniDisableStateDone)
650 } else { //LockStateFSM already init
651 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
652 dh.runUniLockFsm(true)
653 }
654 } else {
655 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
656 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
657 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
658 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
659 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
660 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
661 }
mpagenko01e726e2020-10-23 09:45:29 +0000662 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000663
664 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
665 _ = dh.deviceReasonUpdate(drOmciAdminLock, false)
mpagenko3af1f032020-06-10 08:53:41 +0000666 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300667 }
668}
669
Himani Chawla6d2ae152020-09-02 13:11:20 +0530670//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530671func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000672 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000673
mpagenkofc4f56e2020-11-04 17:17:49 +0000674 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
675 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
676 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
677 // for real ONU's that should have nearly no influence
678 // Note that for real ONU's there is anyway a problematic situation with following sequence:
679 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
680 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
681 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
682 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
683
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000684 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000685 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000686 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000687 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000688 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000689 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000690 dh.runUniLockFsm(false)
691 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300692}
693
Himani Chawla6d2ae152020-09-02 13:11:20 +0530694func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000695 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
696
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000697 pDevEntry := dh.getOnuDeviceEntry(true)
698 if pDevEntry == nil {
699 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
700 return
701 }
702 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000703 if err == fmt.Errorf("no-ONU-data-found") {
704 logger.Debugw("no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
705 } else {
706 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
707 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000708 dh.reconciling = false
709 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000710 }
Himani Chawla4d908332020-08-31 12:30:20 +0530711 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000712 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
713 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
714 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
715 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530716 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000717}
718
Himani Chawla6d2ae152020-09-02 13:11:20 +0530719func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000720 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
721
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000722 pDevEntry := dh.getOnuDeviceEntry(true)
723 if pDevEntry == nil {
724 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
725 return
726 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000727
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000728 dh.pOnuTP.lockTpProcMutex()
729 defer dh.pOnuTP.unlockTpProcMutex()
730
731 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800732 for tpID := range uniData.PersTpPathMap {
733 // deadline context to ensure completion of background routines waited for
734 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
735 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
736 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000737
Girish Gowdra041dcb32020-11-16 16:54:30 -0800738 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
739 var wg sync.WaitGroup
740 wg.Add(1) // for the 1 go routine to finish
741 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
742 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
743 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
744 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
745 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000746 }
747 }
748}
749
750func (dh *deviceHandler) reconcileDeviceFlowConfig() {
751 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
752
753 pDevEntry := dh.getOnuDeviceEntry(true)
754 if pDevEntry == nil {
755 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000756 return
757 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000758 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
759 var uniPort *onuUniPort
760 var exist bool
761 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
762 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000763 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000764 return
765 }
766 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000767 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
768 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000769 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000770 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
771 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
772 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000773 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
774 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000775 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000776 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
777 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000778 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000779 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
780 }
781 }
782 }
783 }
784}
785
786func (dh *deviceHandler) reconcileMetrics() {
787 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
788
789 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000790 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000791}
792
mpagenko2418ab02020-11-12 12:58:06 +0000793func (dh *deviceHandler) deleteDevicePersistencyData() error {
794 logger.Debugw("delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000795
mpagenko2418ab02020-11-12 12:58:06 +0000796 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000797 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000798 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
799 logger.Debugw("OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
800 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000801 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000802 pDevEntry.lockOnuKVStoreMutex()
803 defer pDevEntry.unlockOnuKVStoreMutex()
804
805 // deadline context to ensure completion of background routines waited for
806 //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 +0530807 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808 dctx, cancel := context.WithDeadline(context.Background(), deadline)
809
810 pDevEntry.resetKvProcessingErrorIndication()
811
812 var wg sync.WaitGroup
813 wg.Add(1) // for the 1 go routine to finish
814 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000815 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000817 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000818 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000819}
820
Himani Chawla6d2ae152020-09-02 13:11:20 +0530821func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000822 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300823 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000824 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300826 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530827 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530828 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
829 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
830 return err
831 }
mpagenko01e726e2020-10-23 09:45:29 +0000832
833 //transfer the possibly modified logical uni port state
834 dh.disableUniPortStateUpdate()
835
Andrea Campanellabef4e542020-10-22 11:01:28 +0200836 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000837 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200838 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300839 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000840 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000841 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300842 return err
843 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000844 if err := dh.deviceReasonUpdate(drRebooting, false); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300845 return err
846 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000847 dh.ReadyForSpecificOmciConfig = false
ozgecanetsiae11479f2020-07-06 09:44:47 +0300848 return nil
849}
850
Himani Chawla6d2ae152020-09-02 13:11:20 +0530851// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000852// #####################################################################################
853
854// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530855// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000856
Himani Chawla6d2ae152020-09-02 13:11:20 +0530857func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000858 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})
859}
860
861// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530862func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000863
864 logger.Debug("doStateInit-started")
865 var err error
866
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000867 // populate what we know. rest comes later after mib sync
868 dh.device.Root = false
869 dh.device.Vendor = "OpenONU"
870 dh.device.Model = "go"
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000871 dh.device.Reason = drActivatingOnu
872 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000873
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000874 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000875
876 if !dh.reconciling {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000877 logger.Infow("DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530878 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000879 } else {
880 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
881 log.Fields{"device-id": dh.deviceID})
882 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000883
Himani Chawla4d908332020-08-31 12:30:20 +0530884 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000885 dh.ponPortNumber = dh.device.ParentPortNo
886
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000887 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
888 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
889 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000890 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000891 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530892 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000893
894 /*
895 self._pon = PonPort.create(self, self._pon_port_number)
896 self._pon.add_peer(self.parent_id, self._pon_port_number)
897 self.logger.debug('adding-pon-port-to-agent',
898 type=self._pon.get_port().type,
899 admin_state=self._pon.get_port().admin_state,
900 oper_status=self._pon.get_port().oper_status,
901 )
902 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000903 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000904 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000905 var ponPortNo uint32 = 1
906 if dh.ponPortNumber != 0 {
907 ponPortNo = dh.ponPortNumber
908 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000909
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000910 pPonPort := &voltha.Port{
911 PortNo: ponPortNo,
912 Label: fmt.Sprintf("pon-%d", ponPortNo),
913 Type: voltha.Port_PON_ONU,
914 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530915 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000916 PortNo: ponPortNo}}, // Peer port is parent's port number
917 }
918 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
919 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
920 e.Cancel(err)
921 return
922 }
923 } else {
924 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000925 }
926 logger.Debug("doStateInit-done")
927}
928
929// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530930func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000931
932 logger.Debug("postInit-started")
933 var err error
934 /*
935 dh.Client = oop.NewOpenoltClient(dh.clientCon)
936 dh.pTransitionMap.Handle(ctx, GrpcConnected)
937 return nil
938 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530939 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
940 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000941 e.Cancel(err)
942 return
943 }
944
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000945 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530946 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000947 // reconcilement will be continued after mib download is done
948 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000949 /*
950 ############################################################################
951 # Setup Alarm handler
952 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
953 device.serial_number)
954 ############################################################################
955 # Setup PM configuration for this device
956 # Pass in ONU specific options
957 kwargs = {
958 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
959 'heartbeat': self.heartbeat,
960 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
961 }
962 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
963 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
964 self.logical_device_id, device.serial_number,
965 grouped=True, freq_override=False, **kwargs)
966 pm_config = self._pm_metrics.make_proto()
967 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
968 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
969 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
970
971 # Note, ONU ID and UNI intf set in add_uni_port method
972 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
973 ani_ports=[self._pon])
974
975 # Code to Run OMCI Test Action
976 kwargs_omci_test_action = {
977 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
978 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
979 }
980 serial_number = device.serial_number
981 self._test_request = OmciTestRequest(self.core_proxy,
982 self.omci_agent, self.device_id,
983 AniG, serial_number,
984 self.logical_device_id,
985 exclusive=False,
986 **kwargs_omci_test_action)
987
988 self.enabled = True
989 else:
990 self.logger.info('onu-already-activated')
991 */
992 logger.Debug("postInit-done")
993}
994
995// doStateConnected get the device info and update to voltha core
996// for comparison of the original method (not that easy to uncomment): compare here:
997// voltha-openolt-adapter/adaptercore/device_handler.go
998// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530999func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001000
1001 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301002 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001003 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001004 logger.Debug("doStateConnected-done")
1005}
1006
1007// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301008func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001009
1010 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301011 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001012 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001013 logger.Debug("doStateUp-done")
1014
1015 /*
1016 // Synchronous call to update device state - this method is run in its own go routine
1017 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1018 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001019 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 +00001020 return err
1021 }
1022 return nil
1023 */
1024}
1025
1026// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301027func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001028
1029 logger.Debug("doStateDown-started")
1030 var err error
1031
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001032 device := dh.device
1033 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001034 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001035 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001036 e.Cancel(err)
1037 return
1038 }
1039
1040 cloned := proto.Clone(device).(*voltha.Device)
1041 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1042 /*
1043 // Update the all ports state on that device to disable
1044 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001045 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001046 return er
1047 }
1048
1049 //Update the device oper state and connection status
1050 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1051 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1052 dh.device = cloned
1053
1054 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001055 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001056 return er
1057 }
1058
1059 //get the child device for the parent device
1060 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1061 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001062 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001063 return err
1064 }
1065 for _, onuDevice := range onuDevices.Items {
1066
1067 // Update onu state as down in onu adapter
1068 onuInd := oop.OnuIndication{}
1069 onuInd.OperState = "down"
1070 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1071 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1072 if er != nil {
1073 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001074 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001075 //Do not return here and continue to process other ONUs
1076 }
1077 }
1078 // * Discovered ONUs entries need to be cleared , since after OLT
1079 // is up, it starts sending discovery indications again* /
1080 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001081 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001082 return nil
1083 */
Himani Chawla4d908332020-08-31 12:30:20 +05301084 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001085 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001086 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001087}
1088
Himani Chawla6d2ae152020-09-02 13:11:20 +05301089// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090// #################################################################################
1091
1092// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301093// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001094
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001095//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301096func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001097 dh.lockDevice.RLock()
1098 pOnuDeviceEntry := dh.pOnuOmciDevice
1099 if aWait && pOnuDeviceEntry == nil {
1100 //keep the read sema short to allow for subsequent write
1101 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001102 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001103 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1104 // so it might be needed to wait here for that event with some timeout
1105 select {
1106 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001107 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001108 return nil
1109 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001110 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001111 // if written now, we can return the written value without sema
1112 return dh.pOnuOmciDevice
1113 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114 }
mpagenko3af1f032020-06-10 08:53:41 +00001115 dh.lockDevice.RUnlock()
1116 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001117}
1118
Himani Chawla6d2ae152020-09-02 13:11:20 +05301119//setOnuDeviceEntry sets the ONU device entry within the handler
1120func (dh *deviceHandler) setOnuDeviceEntry(
1121 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001122 dh.lockDevice.Lock()
1123 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001124 dh.pOnuOmciDevice = apDeviceEntry
1125 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001126}
1127
Himani Chawla6d2ae152020-09-02 13:11:20 +05301128//addOnuDeviceEntry creates a new ONU device or returns the existing
1129func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001130 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001131
Himani Chawla6d2ae152020-09-02 13:11:20 +05301132 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 if deviceEntry == nil {
1134 /* costum_me_map in python code seems always to be None,
1135 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1136 /* also no 'clock' argument - usage open ...*/
1137 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001138 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001139 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001140 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301141 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001142 // fire deviceEntry ready event to spread to possibly waiting processing
1143 dh.deviceEntrySet <- true
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001144 logger.Debugw("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001145 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001146 logger.Debugw("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147 }
1148 // might be updated with some error handling !!!
1149 return nil
1150}
1151
1152// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301153func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001154 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1155 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1156
1157 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001158
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001159 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001160 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1161 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001162 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1163 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1164 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1165 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1166 }
1167 } else {
1168 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1169 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001170 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001171 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1172 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1173 // 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 +00001174 // 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 +00001175 // so let's just try to keep it simple ...
1176 /*
1177 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1178 if err != nil || device == nil {
1179 //TODO: needs to handle error scenarios
1180 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1181 return errors.New("Voltha Device not found")
1182 }
1183 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001184
Himani Chawla6d2ae152020-09-02 13:11:20 +05301185 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001186 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301187 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301188 return err
1189 }
mpagenko3af1f032020-06-10 08:53:41 +00001190 } else {
divyadesai4d299552020-08-18 07:13:49 +00001191 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001192 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001193 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001194 _ = dh.deviceReasonUpdate(drStartingOpenomci, dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001195
1196 /* this might be a good time for Omci Verify message? */
1197 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301198 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001199 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001200 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301201 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001202
1203 /* give the handler some time here to wait for the OMCi verification result
1204 after Timeout start and try MibUpload FSM anyway
1205 (to prevent stopping on just not supported OMCI verification from ONU) */
1206 select {
1207 case <-time.After(2 * time.Second):
1208 logger.Warn("omci start-verification timed out (continue normal)")
1209 case testresult := <-verifyExec:
1210 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1211 }
1212
1213 /* In py code it looks earlier (on activate ..)
1214 # Code to Run OMCI Test Action
1215 kwargs_omci_test_action = {
1216 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1217 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1218 }
1219 serial_number = device.serial_number
1220 self._test_request = OmciTestRequest(self.core_proxy,
1221 self.omci_agent, self.device_id,
1222 AniG, serial_number,
1223 self.logical_device_id,
1224 exclusive=False,
1225 **kwargs_omci_test_action)
1226 ...
1227 # Start test requests after a brief pause
1228 if not self._test_request_started:
1229 self._test_request_started = True
1230 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1231 reactor.callLater(tststart, self._test_request.start_collector)
1232
1233 */
1234 /* which is then: in omci_test_request.py : */
1235 /*
1236 def start_collector(self, callback=None):
1237 """
1238 Start the collection loop for an adapter if the frequency > 0
1239
1240 :param callback: (callable) Function to call to collect PM data
1241 """
1242 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1243 if callback is None:
1244 callback = self.perform_test_omci
1245
1246 if self.lc is None:
1247 self.lc = LoopingCall(callback)
1248
1249 if self.default_freq > 0:
1250 self.lc.start(interval=self.default_freq / 10)
1251
1252 def perform_test_omci(self):
1253 """
1254 Perform the initial test request
1255 """
1256 ani_g_entities = self._device.configuration.ani_g_entities
1257 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1258 is not None else None
1259 self._entity_id = ani_g_entities_ids[0]
1260 self.logger.info('perform-test', entity_class=self._entity_class,
1261 entity_id=self._entity_id)
1262 try:
1263 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1264 result = yield self._device.omci_cc.send(frame)
1265 if not result.fields['omci_message'].fields['success_code']:
1266 self.logger.info('Self-Test Submitted Successfully',
1267 code=result.fields[
1268 'omci_message'].fields['success_code'])
1269 else:
1270 raise TestFailure('Test Failure: {}'.format(
1271 result.fields['omci_message'].fields['success_code']))
1272 except TimeoutError as e:
1273 self.deferred.errback(failure.Failure(e))
1274
1275 except Exception as e:
1276 self.logger.exception('perform-test-Error', e=e,
1277 class_id=self._entity_class,
1278 entity_id=self._entity_id)
1279 self.deferred.errback(failure.Failure(e))
1280
1281 */
1282
1283 // PM related heartbeat??? !!!TODO....
1284 //self._heartbeat.enabled = True
1285
mpagenko1cc3cb42020-07-27 15:24:38 +00001286 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1287 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1288 * 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 +05301289 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001290 */
1291 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001292 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001293 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001294 if pMibUlFsm.Is(ulStDisabled) {
1295 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001296 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001297 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301298 }
1299 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1300 //Determine ONU status and start/re-start MIB Synchronization tasks
1301 //Determine if this ONU has ever synchronized
1302 if true { //TODO: insert valid check
1303 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001304 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 +00001305 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001306 }
Himani Chawla4d908332020-08-31 12:30:20 +05301307 } else {
1308 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001309 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 +00001310 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301311 }
1312 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1313 //Examine the MIB Data Sync
1314 // callbacks to be handled:
1315 // Event(ulEvSuccess)
1316 // Event(ulEvTimeout)
1317 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001318 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001319 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001320 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001321 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001322 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001323 }
1324 } else {
divyadesai4d299552020-08-18 07:13:49 +00001325 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001326 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001327 }
1328 return nil
1329}
1330
Himani Chawla6d2ae152020-09-02 13:11:20 +05301331func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001332 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001333 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001334 if dh.deviceReason != drStoppingOpenomci {
divyadesai4d299552020-08-18 07:13:49 +00001335 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001336
mpagenko900ee4b2020-10-12 11:56:34 +00001337 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1338 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1339 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1340 if err := dh.resetFsms(); err != nil {
1341 logger.Errorw("error-updateInterface at FSM stop",
1342 log.Fields{"device-id": dh.deviceID, "error": err})
1343 // abort: system behavior is just unstable ...
1344 return err
1345 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001346 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
mpagenko2418ab02020-11-12 12:58:06 +00001347 _ = dh.deleteDevicePersistencyData() //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001348
1349 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1350 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1351 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301352 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001353 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001354 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001355 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001356 }
mpagenko900ee4b2020-10-12 11:56:34 +00001357 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001358
1359 //TODO!!! remove existing traffic profiles
1360 /* from py code, if TP's exist, remove them - not yet implemented
1361 self._tp = dict()
1362 # Let TP download happen again
1363 for uni_id in self._tp_service_specific_task:
1364 self._tp_service_specific_task[uni_id].clear()
1365 for uni_id in self._tech_profile_download_done:
1366 self._tech_profile_download_done[uni_id].clear()
1367 */
1368
1369 dh.disableUniPortStateUpdate()
1370
mpagenkofc4f56e2020-11-04 17:17:49 +00001371 dh.ReadyForSpecificOmciConfig = false
1372
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001373 if err := dh.deviceReasonUpdate(drStoppingOpenomci, false); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001374 // abort: system behavior is just unstable ...
1375 return err
1376 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001377 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1378 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001379 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1380 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001381 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001382 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001383 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001384 // abort: system behavior is just unstable ...
1385 return err
1386 }
1387 } else {
divyadesai4d299552020-08-18 07:13:49 +00001388 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001389 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001390 return nil
1391}
1392
mpagenko900ee4b2020-10-12 11:56:34 +00001393func (dh *deviceHandler) resetFsms() error {
1394 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1395 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1396 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1397 // and using the stop/reset event should never harm
1398
1399 pDevEntry := dh.getOnuDeviceEntry(false)
1400 if pDevEntry == nil {
1401 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1402 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1403 }
1404
1405 //the MibSync FSM might be active all the ONU-active time,
1406 // hence it must be stopped unconditionally
1407 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1408 if pMibUlFsm != nil {
1409 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1410 }
1411 //MibDownload may run
1412 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1413 if pMibDlFsm != nil {
1414 _ = pMibDlFsm.Event(dlEvReset)
1415 }
1416 //port lock/unlock FSM's may be active
1417 if dh.pUnlockStateFsm != nil {
1418 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1419 }
1420 if dh.pLockStateFsm != nil {
1421 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1422 }
1423 //techProfile related PonAniConfigFsm FSM may be active
1424 if dh.pOnuTP != nil {
1425 // should always be the case here
1426 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1427 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001428 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1429 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1430 }
mpagenko900ee4b2020-10-12 11:56:34 +00001431 }
1432 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001433 // reset the possibly existing VlanConfigFsm
1434 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1435 //VlanFilterFsm exists and was already started
1436 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1437 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001438 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001439 // no need to remove specific data
1440 pVlanFilterFsm.RequestClearPersistency(false)
1441 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001442 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1443 }
1444 }
1445 }
1446 }
1447 //TODO!!! care about PM/Alarm processing once started
1448 return nil
1449}
1450
Himani Chawla6d2ae152020-09-02 13:11:20 +05301451func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001452 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 +05301453
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001454 _ = dh.deviceReasonUpdate(drDiscoveryMibsyncComplete, dh.reconciling)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301455 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenkoa40e99a2020-11-17 13:50:39 +00001456 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301457 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301458 for _, mgmtEntityID := range unigInstKeys {
1459 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1460 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301461 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301462 i++
1463 }
1464 } else {
1465 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1466 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301467 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301468 for _, mgmtEntityID := range veipInstKeys {
1469 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1470 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301471 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301472 i++
1473 }
1474 } else {
1475 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1476 }
1477 if i == 0 {
1478 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1479 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001480 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1481 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1482 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1483 * disable/enable toggling here to allow traffic
1484 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1485 * like the py comment says:
1486 * # start by locking all the unis till mib sync and initial mib is downloaded
1487 * # this way we can capture the port down/up events when we are ready
1488 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301489
mpagenkoa40e99a2020-11-17 13:50:39 +00001490 // Init Uni Ports to Admin locked state
1491 // *** should generate UniLockStateDone event *****
1492 if dh.pLockStateFsm == nil {
1493 dh.createUniLockFsm(true, UniLockStateDone)
1494 } else { //LockStateFSM already init
1495 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
1496 dh.runUniLockFsm(true)
1497 }
1498}
1499
1500func (dh *deviceHandler) processUniLockStateDoneEvent(devEvent OnuDeviceEvent) {
1501 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301502 /* Mib download procedure -
1503 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1504 */
mpagenkoa40e99a2020-11-17 13:50:39 +00001505 pDevEntry := dh.getOnuDeviceEntry(false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301506 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1507 if pMibDlFsm != nil {
1508 if pMibDlFsm.Is(dlStDisabled) {
1509 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001510 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301511 // maybe try a FSM reset and then again ... - TODO!!!
1512 } else {
1513 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1514 // maybe use more specific states here for the specific download steps ...
1515 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001516 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301517 } else {
1518 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1519 //Begin MIB data download (running autonomously)
1520 }
1521 }
1522 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001523 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001524 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301525 // maybe try a FSM reset and then again ... - TODO!!!
1526 }
1527 /***** Mib download started */
1528 } else {
1529 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1530 }
1531}
1532
Himani Chawla6d2ae152020-09-02 13:11:20 +05301533func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001534 logger.Debugw("MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301535 //initiate DevStateUpdate
1536 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001537 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1538 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301539 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1540 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1541 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1542 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1543 } else {
1544 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1545 }
1546 } else {
1547 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1548 log.Fields{"device-id": dh.deviceID})
1549 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001550 _ = dh.deviceReasonUpdate(drInitialMibDownloaded, dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001551 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301552 // *** should generate UniUnlockStateDone event *****
1553 if dh.pUnlockStateFsm == nil {
1554 dh.createUniLockFsm(false, UniUnlockStateDone)
1555 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301556 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301557 dh.runUniLockFsm(false)
1558 }
1559}
1560
Himani Chawla6d2ae152020-09-02 13:11:20 +05301561func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001562 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301563
1564 if !dh.reconciling {
1565 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1566 raisedTs := time.Now().UnixNano()
1567 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1568 } else {
1569 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1570 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301571 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001572 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301573 }
1574}
1575
mpagenko900ee4b2020-10-12 11:56:34 +00001576func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1577 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1578 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1579 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1580 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1581 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1582 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1583 }
1584
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001585 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{"reason": drOmciAdminLock, "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001586 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001587 _ = dh.deviceReasonUpdate(drOmciAdminLock, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001588
1589 //transfer the modified logical uni port state
1590 dh.disableUniPortStateUpdate()
mpagenko900ee4b2020-10-12 11:56:34 +00001591}
1592
1593func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1594 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1595 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1596 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1597 voltha.OperStatus_ACTIVE); err != nil {
1598 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1599 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1600 }
1601
1602 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001603 "reason": drOnuReenabled, "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001604 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001605 _ = dh.deviceReasonUpdate(drOnuReenabled, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001606
1607 //transfer the modified logical uni port state
1608 dh.enableUniPortStateUpdate()
1609}
1610
Himani Chawla6d2ae152020-09-02 13:11:20 +05301611func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001612 if devEvent == OmciAniConfigDone {
1613 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1614 // attention: the device reason update is done based on ONU-UNI-Port related activity
1615 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001616 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001617 // 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 +00001618 _ = dh.deviceReasonUpdate(drTechProfileConfigDownloadSuccess, dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301619 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001620 if dh.reconciling {
1621 go dh.reconcileDeviceFlowConfig()
1622 }
1623 } else { // should be the OmciAniResourceRemoved block
1624 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1625 // attention: the device reason update is done based on ONU-UNI-Port related activity
1626 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001627 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001628 // 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 +00001629 _ = dh.deviceReasonUpdate(drTechProfileConfigDeleteSuccess, false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001630 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001631 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301632}
1633
mpagenkofc4f56e2020-11-04 17:17:49 +00001634func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301635 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001636 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301637 // attention: the device reason update is done based on ONU-UNI-Port related activity
1638 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301639
mpagenkofc4f56e2020-11-04 17:17:49 +00001640 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001641 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001642 // which may be the case from some previous actvity on another UNI Port of the ONU
1643 // or even some previous flow add activity on the same port
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001644 _ = dh.deviceReasonUpdate(drOmciFlowsPushed, dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001645 if dh.reconciling {
1646 go dh.reconcileMetrics()
1647 }
1648 }
1649 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001650 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001651 //not relevant for reconcile
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001652 _ = dh.deviceReasonUpdate(drOmciFlowsDeleted, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001653 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301654 }
1655}
1656
Himani Chawla6d2ae152020-09-02 13:11:20 +05301657//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1658func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301659 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001660 case MibDatabaseSync:
1661 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301662 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001663 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001664 case UniLockStateDone:
1665 {
1666 dh.processUniLockStateDoneEvent(devEvent)
1667 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001668 case MibDownloadDone:
1669 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301670 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001671 }
1672 case UniUnlockStateDone:
1673 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301674 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001675 }
mpagenko900ee4b2020-10-12 11:56:34 +00001676 case UniEnableStateDone:
1677 {
1678 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001679 }
1680 case UniDisableStateDone:
1681 {
1682 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001683 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001684 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001685 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301686 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001687 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001688 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001689 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301690 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001691 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001692 default:
1693 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001694 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001695 }
1696 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697}
1698
Himani Chawla6d2ae152020-09-02 13:11:20 +05301699func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001700 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301701 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301702 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001703 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301704 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301706 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301707 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001708 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301709 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001711 //store UniPort with the System-PortNumber key
1712 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001713 if !dh.reconciling {
1714 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301715 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001716 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1717 } //error logging already within UniPort method
1718 } else {
1719 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1720 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001721 }
1722 }
1723}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001724
mpagenko3af1f032020-06-10 08:53:41 +00001725// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301726func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001727 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301728 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001729 // with following remark:
1730 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1731 // # load on the core
1732
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001733 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001734
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001735 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001736 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301737 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001738 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301739 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001740 if !dh.reconciling {
1741 //maybe also use getter functions on uniPort - perhaps later ...
1742 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1743 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001744 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001745 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1746 }
mpagenko3af1f032020-06-10 08:53:41 +00001747 }
1748 }
1749}
1750
1751// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301752func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001753 // compare enableUniPortStateUpdate() above
1754 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1755 for uniNo, uniPort := range dh.uniEntityMap {
1756 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301757 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001758 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301759 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001760 //maybe also use getter functions on uniPort - perhaps later ...
1761 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001762 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001763 }
1764}
1765
1766// ONU_Active/Inactive announcement on system KAFKA bus
1767// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301768func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001769 var de voltha.DeviceEvent
1770 eventContext := make(map[string]string)
1771 //Populating event context
1772 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301773 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001774 if err != nil || parentDevice == nil {
1775 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301776 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001777 }
1778 oltSerialNumber := parentDevice.SerialNumber
1779
1780 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1781 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1782 eventContext["serial-number"] = dh.device.SerialNumber
1783 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301784 eventContext["device_id"] = aDeviceID
1785 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001786 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001787 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001788
1789 /* Populating device event body */
1790 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301791 de.ResourceId = aDeviceID
1792 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001793 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1794 de.Description = fmt.Sprintf("%s Event - %s - %s",
1795 cEventObjectType, cOnuActivatedEvent, "Raised")
1796 } else {
1797 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1798 de.Description = fmt.Sprintf("%s Event - %s - %s",
1799 cEventObjectType, cOnuActivatedEvent, "Cleared")
1800 }
1801 /* Send event to KAFKA */
1802 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1803 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301804 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001805 }
1806 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301807 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001808}
1809
Himani Chawla4d908332020-08-31 12:30:20 +05301810// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301811func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001812 chLSFsm := make(chan Message, 2048)
1813 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301814 if aAdminState {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001815 logger.Debugw("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001816 sFsmName = "LockStateFSM"
1817 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001818 logger.Debugw("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001819 sFsmName = "UnLockStateFSM"
1820 }
mpagenko3af1f032020-06-10 08:53:41 +00001821
Himani Chawla6d2ae152020-09-02 13:11:20 +05301822 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001823 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001824 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001825 return
1826 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301827 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001828 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001829 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301830 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001831 dh.pLockStateFsm = pLSFsm
1832 } else {
1833 dh.pUnlockStateFsm = pLSFsm
1834 }
1835 dh.runUniLockFsm(aAdminState)
1836 } else {
divyadesai4d299552020-08-18 07:13:49 +00001837 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001838 }
1839}
1840
1841// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301842func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001843 /* Uni Port lock/unlock procedure -
1844 ***** should run via 'adminDone' state and generate the argument requested event *****
1845 */
1846 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301847 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001848 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1849 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1850 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001851 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301852 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001853 }
1854 } else {
1855 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1856 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1857 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001858 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301859 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001860 }
1861 }
1862 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001863 if pLSStatemachine.Is(uniStDisabled) {
1864 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001865 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1866 // maybe try a FSM reset and then again ... - TODO!!!
1867 } else {
1868 /***** LockStateFSM started */
1869 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001870 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001871 }
1872 } else {
1873 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001874 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001875 // maybe try a FSM reset and then again ... - TODO!!!
1876 }
1877 } else {
divyadesai4d299552020-08-18 07:13:49 +00001878 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001879 // maybe try a FSM reset and then again ... - TODO!!!
1880 }
1881}
1882
Himani Chawla6d2ae152020-09-02 13:11:20 +05301883//setBackend provides a DB backend for the specified path on the existing KV client
1884func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001885 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1886 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001887 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001888 kvbackend := &db.Backend{
1889 Client: dh.pOpenOnuAc.kvClient,
1890 StoreType: dh.pOpenOnuAc.KVStoreType,
1891 /* address config update acc. to [VOL-2736] */
1892 Address: addr,
1893 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1894 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001895
mpagenkoaf801632020-07-03 10:00:42 +00001896 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001897}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301898func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301899 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001900
mpagenkodff5dda2020-08-28 11:52:01 +00001901 for _, field := range flow.GetOfbFields(apFlowItem) {
1902 switch field.Type {
1903 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1904 {
mpagenko01e726e2020-10-23 09:45:29 +00001905 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001906 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1907 }
mpagenko01e726e2020-10-23 09:45:29 +00001908 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00001909 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1910 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301911 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00001912 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301913 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1914 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001915 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1916 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00001917 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
1918 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301919 return
mpagenkodff5dda2020-08-28 11:52:01 +00001920 }
1921 }
mpagenko01e726e2020-10-23 09:45:29 +00001922 */
mpagenkodff5dda2020-08-28 11:52:01 +00001923 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1924 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301925 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001926 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301927 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001928 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301929 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001930 }
mpagenko01e726e2020-10-23 09:45:29 +00001931 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301932 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001933 }
1934 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1935 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301936 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00001937 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001938 "PCP": loAddPcp})
1939 }
1940 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1941 {
mpagenko01e726e2020-10-23 09:45:29 +00001942 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001943 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1944 }
1945 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1946 {
mpagenko01e726e2020-10-23 09:45:29 +00001947 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001948 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1949 }
1950 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1951 {
mpagenko01e726e2020-10-23 09:45:29 +00001952 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001953 "IPv4-DST": field.GetIpv4Dst()})
1954 }
1955 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1956 {
mpagenko01e726e2020-10-23 09:45:29 +00001957 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001958 "IPv4-SRC": field.GetIpv4Src()})
1959 }
1960 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1961 {
mpagenko01e726e2020-10-23 09:45:29 +00001962 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001963 "Metadata": field.GetTableMetadata()})
1964 }
1965 /*
1966 default:
1967 {
1968 //all other entires ignored
1969 }
1970 */
1971 }
1972 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301973}
mpagenkodff5dda2020-08-28 11:52:01 +00001974
Himani Chawla6d2ae152020-09-02 13:11:20 +05301975func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001976 for _, action := range flow.GetActions(apFlowItem) {
1977 switch action.Type {
1978 /* not used:
1979 case of.OfpActionType_OFPAT_OUTPUT:
1980 {
mpagenko01e726e2020-10-23 09:45:29 +00001981 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001982 "Output": action.GetOutput()})
1983 }
1984 */
1985 case of.OfpActionType_OFPAT_PUSH_VLAN:
1986 {
mpagenko01e726e2020-10-23 09:45:29 +00001987 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001988 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1989 }
1990 case of.OfpActionType_OFPAT_SET_FIELD:
1991 {
1992 pActionSetField := action.GetSetField()
1993 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00001994 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001995 "OxcmClass": pActionSetField.Field.OxmClass})
1996 }
1997 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05301998 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00001999 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302000 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002001 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302002 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002003 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302004 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002005 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002006 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002007 "Type": pActionSetField.Field.GetOfbField().Type})
2008 }
2009 }
2010 /*
2011 default:
2012 {
2013 //all other entires ignored
2014 }
2015 */
2016 }
2017 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302018}
2019
2020//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302021func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302022 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2023 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2024 var loAddPcp, loSetPcp uint8
2025 var loIPProto uint32
2026 /* the TechProfileId is part of the flow Metadata - compare also comment within
2027 * OLT-Adapter:openolt_flowmgr.go
2028 * Metadata 8 bytes:
2029 * Most Significant 2 Bytes = Inner VLAN
2030 * Next 2 Bytes = Tech Profile ID(TPID)
2031 * Least Significant 4 Bytes = Port ID
2032 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2033 * subscriber related flows.
2034 */
2035
2036 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2037 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002038 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302039 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002040 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302041 }
2042 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002043 loCookie := apFlowItem.GetCookie()
2044 loCookieSlice := []uint64{loCookie}
2045 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2046 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302047
2048 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002049 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302050 if loIPProto == 2 {
2051 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2052 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002053 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2054 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302055 return nil
2056 }
mpagenko01e726e2020-10-23 09:45:29 +00002057 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302058 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002059
2060 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002061 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002062 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2063 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2064 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2065 //TODO!!: Use DeviceId within the error response to rwCore
2066 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002067 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002068 }
2069 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002070 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002071 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2072 } else {
2073 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2074 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2075 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302076 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002077 }
mpagenko01e726e2020-10-23 09:45:29 +00002078 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002079 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302080 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002081 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2082 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002083 }
mpagenko01e726e2020-10-23 09:45:29 +00002084 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002085 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002086}
2087
2088//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2089func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2090 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2091 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2092 //no extra check is done on the rule parameters
2093 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2094 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2095 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2096 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002097 // - 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 +00002098 loCookie := apFlowItem.GetCookie()
2099 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2100
2101 /* TT related temporary workaround - should not be needed anymore
2102 for _, field := range flow.GetOfbFields(apFlowItem) {
2103 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2104 loIPProto := field.GetIpProto()
2105 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2106 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2107 if loIPProto == 2 {
2108 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2109 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2110 log.Fields{"device-id": dh.deviceID})
2111 return nil
2112 }
2113 }
2114 } //for all OfbFields
2115 */
2116
2117 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2118 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2119 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002120 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002121 log.Fields{"device-id": dh.deviceID})
2122 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002123 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2124 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2125
mpagenko01e726e2020-10-23 09:45:29 +00002126 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002127}
2128
Himani Chawla26e555c2020-08-31 12:30:20 +05302129// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002130func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2131 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002132 chVlanFilterFsm := make(chan Message, 2048)
2133
Himani Chawla6d2ae152020-09-02 13:11:20 +05302134 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002135 if pDevEntry == nil {
2136 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302137 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002138 }
2139
2140 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002141 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2142 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002143 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302144 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002145 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2146 if pVlanFilterStatemachine != nil {
2147 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2148 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2149 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302150 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002151 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302152 /***** UniVlanConfigFsm started */
2153 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2154 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2155 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002156 } else {
2157 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2158 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302159 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002160 }
2161 } else {
2162 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2163 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302164 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002165 }
2166 } else {
2167 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2168 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302169 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002170 }
2171 return nil
2172}
2173
mpagenkofc4f56e2020-11-04 17:17:49 +00002174//VerifyVlanConfigRequest checks on existence of a given uniPort
2175// and starts verification of flow config based on that
2176func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2177 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2178 var pCurrentUniPort *onuUniPort
2179 for _, uniPort := range dh.uniEntityMap {
2180 // only if this port is validated for operState transfer
2181 if uniPort.uniID == uint8(aUniID) {
2182 pCurrentUniPort = uniPort
2183 break //found - end search loop
2184 }
2185 }
2186 if pCurrentUniPort == nil {
2187 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2188 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2189 return
2190 }
2191 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2192}
2193
mpagenkodff5dda2020-08-28 11:52:01 +00002194//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302195func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002196 //TODO!! verify and start pending flow configuration
2197 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2198 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302199 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002200 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2201 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2202 if pVlanFilterStatemachine != nil {
2203 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2204 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2205 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2206 } else {
2207 /***** UniVlanConfigFsm continued */
2208 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2209 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2210 "UniPort": apUniPort.portNo})
2211 }
2212 } else {
2213 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2214 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2215 }
2216 } else {
2217 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2218 "device-id": dh.deviceID})
2219 }
2220
2221 } // else: nothing to do
2222}
2223
2224//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2225// 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 +05302226func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002227 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2228 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2229 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302230 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002231}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002232
2233//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2234//available for potential reconcilement
2235
2236func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2237
2238 if dh.reconciling {
2239 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2240 return nil
2241 }
mpagenko2418ab02020-11-12 12:58:06 +00002242 logger.Debugw("Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002243
2244 pDevEntry := dh.getOnuDeviceEntry(true)
2245 if pDevEntry == nil {
2246 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2247 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2248 }
2249 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2250
2251 pDevEntry.lockOnuKVStoreMutex()
2252 defer pDevEntry.unlockOnuKVStoreMutex()
2253
2254 // deadline context to ensure completion of background routines waited for
2255 //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 +05302256 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002257 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2258
2259 pDevEntry.resetKvProcessingErrorIndication()
2260 var wg sync.WaitGroup
2261 wg.Add(1) // for the 1 go routine to finish
2262
2263 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002264 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002265
2266 return pDevEntry.getKvProcessingErrorIndication()
2267}
2268
mpagenko01e726e2020-10-23 09:45:29 +00002269func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002270 defer cancel() //ensure termination of context (may be pro forma)
2271 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002272 logger.Debugw("WaitGroup processing completed", log.Fields{
2273 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002274}
2275
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002276func (dh *deviceHandler) deviceReasonUpdate(deviceReason string, dontNotifyCore bool) error {
2277
2278 dh.deviceReason = deviceReason
2279 if !dontNotifyCore {
2280 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
2281 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, deviceReason); err != nil {
2282 logger.Errorw("DeviceReasonUpdate: error",
2283 log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID, "error": err})
2284 return err
2285 }
2286 logger.Infow("DeviceReasonUpdate: success", log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID})
2287 return nil
2288 }
2289 logger.Infow("Don't notify core about DeviceReasonUpdate", log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID})
2290 return nil
2291}
2292
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002293func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2294 var errStr string = ""
2295 for _, err := range errS {
2296 if err != nil {
2297 errStr = errStr + err.Error() + " "
2298 }
2299 }
2300 if errStr != "" {
2301 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2302 }
2303 return nil
2304}