blob: e2b847da54a9c65afeac82d0d9dc82cbf078f1d1 [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
mpagenko8b07c1b2020-11-26 10:36:31 +0000397 go dh.pOnuTP.deleteTpResource(dctx, uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000398 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
mpagenko8b07c1b2020-11-26 10:36:31 +0000457 go dh.pOnuTP.deleteTpResource(dctx, uniID, tpID, 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
mpagenko8b07c1b2020-11-26 10:36:31 +0000848 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
849 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
850 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
851 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300852 return nil
853}
854
Himani Chawla6d2ae152020-09-02 13:11:20 +0530855// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000856// #####################################################################################
857
858// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530859// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000860
Himani Chawla6d2ae152020-09-02 13:11:20 +0530861func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000862 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})
863}
864
865// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530866func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000867
868 logger.Debug("doStateInit-started")
869 var err error
870
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000871 // populate what we know. rest comes later after mib sync
872 dh.device.Root = false
873 dh.device.Vendor = "OpenONU"
874 dh.device.Model = "go"
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000875 dh.device.Reason = drActivatingOnu
876 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000877
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000878 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000879
880 if !dh.reconciling {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000881 logger.Infow("DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530882 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000883 } else {
884 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
885 log.Fields{"device-id": dh.deviceID})
886 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000887
Himani Chawla4d908332020-08-31 12:30:20 +0530888 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000889 dh.ponPortNumber = dh.device.ParentPortNo
890
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000891 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
892 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
893 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000894 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000895 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530896 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000897
898 /*
899 self._pon = PonPort.create(self, self._pon_port_number)
900 self._pon.add_peer(self.parent_id, self._pon_port_number)
901 self.logger.debug('adding-pon-port-to-agent',
902 type=self._pon.get_port().type,
903 admin_state=self._pon.get_port().admin_state,
904 oper_status=self._pon.get_port().oper_status,
905 )
906 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000907 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000908 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000909 var ponPortNo uint32 = 1
910 if dh.ponPortNumber != 0 {
911 ponPortNo = dh.ponPortNumber
912 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000913
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000914 pPonPort := &voltha.Port{
915 PortNo: ponPortNo,
916 Label: fmt.Sprintf("pon-%d", ponPortNo),
917 Type: voltha.Port_PON_ONU,
918 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530919 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000920 PortNo: ponPortNo}}, // Peer port is parent's port number
921 }
922 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
923 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
924 e.Cancel(err)
925 return
926 }
927 } else {
928 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000929 }
930 logger.Debug("doStateInit-done")
931}
932
933// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530934func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000935
936 logger.Debug("postInit-started")
937 var err error
938 /*
939 dh.Client = oop.NewOpenoltClient(dh.clientCon)
940 dh.pTransitionMap.Handle(ctx, GrpcConnected)
941 return nil
942 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530943 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
944 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000945 e.Cancel(err)
946 return
947 }
948
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000949 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530950 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000951 // reconcilement will be continued after mib download is done
952 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000953 /*
954 ############################################################################
955 # Setup Alarm handler
956 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
957 device.serial_number)
958 ############################################################################
959 # Setup PM configuration for this device
960 # Pass in ONU specific options
961 kwargs = {
962 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
963 'heartbeat': self.heartbeat,
964 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
965 }
966 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
967 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
968 self.logical_device_id, device.serial_number,
969 grouped=True, freq_override=False, **kwargs)
970 pm_config = self._pm_metrics.make_proto()
971 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
972 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
973 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
974
975 # Note, ONU ID and UNI intf set in add_uni_port method
976 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
977 ani_ports=[self._pon])
978
979 # Code to Run OMCI Test Action
980 kwargs_omci_test_action = {
981 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
982 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
983 }
984 serial_number = device.serial_number
985 self._test_request = OmciTestRequest(self.core_proxy,
986 self.omci_agent, self.device_id,
987 AniG, serial_number,
988 self.logical_device_id,
989 exclusive=False,
990 **kwargs_omci_test_action)
991
992 self.enabled = True
993 else:
994 self.logger.info('onu-already-activated')
995 */
996 logger.Debug("postInit-done")
997}
998
999// doStateConnected get the device info and update to voltha core
1000// for comparison of the original method (not that easy to uncomment): compare here:
1001// voltha-openolt-adapter/adaptercore/device_handler.go
1002// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +05301003func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001004
1005 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301006 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001007 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001008 logger.Debug("doStateConnected-done")
1009}
1010
1011// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301012func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001013
1014 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301015 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001016 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001017 logger.Debug("doStateUp-done")
1018
1019 /*
1020 // Synchronous call to update device state - this method is run in its own go routine
1021 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1022 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001023 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 +00001024 return err
1025 }
1026 return nil
1027 */
1028}
1029
1030// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301031func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001032
1033 logger.Debug("doStateDown-started")
1034 var err error
1035
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001036 device := dh.device
1037 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001038 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001039 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001040 e.Cancel(err)
1041 return
1042 }
1043
1044 cloned := proto.Clone(device).(*voltha.Device)
1045 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1046 /*
1047 // Update the all ports state on that device to disable
1048 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001049 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050 return er
1051 }
1052
1053 //Update the device oper state and connection status
1054 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1055 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1056 dh.device = cloned
1057
1058 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001059 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001060 return er
1061 }
1062
1063 //get the child device for the parent device
1064 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1065 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001066 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001067 return err
1068 }
1069 for _, onuDevice := range onuDevices.Items {
1070
1071 // Update onu state as down in onu adapter
1072 onuInd := oop.OnuIndication{}
1073 onuInd.OperState = "down"
1074 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1075 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1076 if er != nil {
1077 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001078 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001079 //Do not return here and continue to process other ONUs
1080 }
1081 }
1082 // * Discovered ONUs entries need to be cleared , since after OLT
1083 // is up, it starts sending discovery indications again* /
1084 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001085 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001086 return nil
1087 */
Himani Chawla4d908332020-08-31 12:30:20 +05301088 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001089 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001091}
1092
Himani Chawla6d2ae152020-09-02 13:11:20 +05301093// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001094// #################################################################################
1095
1096// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301097// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001098
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001099//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301100func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001101 dh.lockDevice.RLock()
1102 pOnuDeviceEntry := dh.pOnuOmciDevice
1103 if aWait && pOnuDeviceEntry == nil {
1104 //keep the read sema short to allow for subsequent write
1105 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001106 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001107 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1108 // so it might be needed to wait here for that event with some timeout
1109 select {
1110 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001111 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001112 return nil
1113 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001114 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001115 // if written now, we can return the written value without sema
1116 return dh.pOnuOmciDevice
1117 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001118 }
mpagenko3af1f032020-06-10 08:53:41 +00001119 dh.lockDevice.RUnlock()
1120 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121}
1122
Himani Chawla6d2ae152020-09-02 13:11:20 +05301123//setOnuDeviceEntry sets the ONU device entry within the handler
1124func (dh *deviceHandler) setOnuDeviceEntry(
1125 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001126 dh.lockDevice.Lock()
1127 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001128 dh.pOnuOmciDevice = apDeviceEntry
1129 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130}
1131
Himani Chawla6d2ae152020-09-02 13:11:20 +05301132//addOnuDeviceEntry creates a new ONU device or returns the existing
1133func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001134 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135
Himani Chawla6d2ae152020-09-02 13:11:20 +05301136 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001137 if deviceEntry == nil {
1138 /* costum_me_map in python code seems always to be None,
1139 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1140 /* also no 'clock' argument - usage open ...*/
1141 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001142 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001143 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301145 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001146 // fire deviceEntry ready event to spread to possibly waiting processing
1147 dh.deviceEntrySet <- true
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001148 logger.Debugw("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001149 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001150 logger.Debugw("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001151 }
1152 // might be updated with some error handling !!!
1153 return nil
1154}
1155
1156// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301157func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001158 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1159 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1160
1161 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001162
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001163 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001164 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1165 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001166 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1167 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1168 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1169 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1170 }
1171 } else {
1172 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1173 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001174 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001175 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1176 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1177 // 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 +00001178 // 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 +00001179 // so let's just try to keep it simple ...
1180 /*
1181 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1182 if err != nil || device == nil {
1183 //TODO: needs to handle error scenarios
1184 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1185 return errors.New("Voltha Device not found")
1186 }
1187 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001188
Himani Chawla6d2ae152020-09-02 13:11:20 +05301189 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001190 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301191 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301192 return err
1193 }
mpagenko3af1f032020-06-10 08:53:41 +00001194 } else {
divyadesai4d299552020-08-18 07:13:49 +00001195 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001196 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001197 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001198 _ = dh.deviceReasonUpdate(drStartingOpenomci, dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001199
1200 /* this might be a good time for Omci Verify message? */
1201 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301202 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001203 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001204 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301205 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206
1207 /* give the handler some time here to wait for the OMCi verification result
1208 after Timeout start and try MibUpload FSM anyway
1209 (to prevent stopping on just not supported OMCI verification from ONU) */
1210 select {
1211 case <-time.After(2 * time.Second):
1212 logger.Warn("omci start-verification timed out (continue normal)")
1213 case testresult := <-verifyExec:
1214 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1215 }
1216
1217 /* In py code it looks earlier (on activate ..)
1218 # Code to Run OMCI Test Action
1219 kwargs_omci_test_action = {
1220 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1221 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1222 }
1223 serial_number = device.serial_number
1224 self._test_request = OmciTestRequest(self.core_proxy,
1225 self.omci_agent, self.device_id,
1226 AniG, serial_number,
1227 self.logical_device_id,
1228 exclusive=False,
1229 **kwargs_omci_test_action)
1230 ...
1231 # Start test requests after a brief pause
1232 if not self._test_request_started:
1233 self._test_request_started = True
1234 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1235 reactor.callLater(tststart, self._test_request.start_collector)
1236
1237 */
1238 /* which is then: in omci_test_request.py : */
1239 /*
1240 def start_collector(self, callback=None):
1241 """
1242 Start the collection loop for an adapter if the frequency > 0
1243
1244 :param callback: (callable) Function to call to collect PM data
1245 """
1246 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1247 if callback is None:
1248 callback = self.perform_test_omci
1249
1250 if self.lc is None:
1251 self.lc = LoopingCall(callback)
1252
1253 if self.default_freq > 0:
1254 self.lc.start(interval=self.default_freq / 10)
1255
1256 def perform_test_omci(self):
1257 """
1258 Perform the initial test request
1259 """
1260 ani_g_entities = self._device.configuration.ani_g_entities
1261 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1262 is not None else None
1263 self._entity_id = ani_g_entities_ids[0]
1264 self.logger.info('perform-test', entity_class=self._entity_class,
1265 entity_id=self._entity_id)
1266 try:
1267 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1268 result = yield self._device.omci_cc.send(frame)
1269 if not result.fields['omci_message'].fields['success_code']:
1270 self.logger.info('Self-Test Submitted Successfully',
1271 code=result.fields[
1272 'omci_message'].fields['success_code'])
1273 else:
1274 raise TestFailure('Test Failure: {}'.format(
1275 result.fields['omci_message'].fields['success_code']))
1276 except TimeoutError as e:
1277 self.deferred.errback(failure.Failure(e))
1278
1279 except Exception as e:
1280 self.logger.exception('perform-test-Error', e=e,
1281 class_id=self._entity_class,
1282 entity_id=self._entity_id)
1283 self.deferred.errback(failure.Failure(e))
1284
1285 */
1286
1287 // PM related heartbeat??? !!!TODO....
1288 //self._heartbeat.enabled = True
1289
mpagenko1cc3cb42020-07-27 15:24:38 +00001290 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1291 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1292 * 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 +05301293 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001294 */
1295 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001296 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001297 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001298 if pMibUlFsm.Is(ulStDisabled) {
1299 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001300 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001301 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301302 }
1303 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1304 //Determine ONU status and start/re-start MIB Synchronization tasks
1305 //Determine if this ONU has ever synchronized
1306 if true { //TODO: insert valid check
1307 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001308 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 +00001309 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001310 }
Himani Chawla4d908332020-08-31 12:30:20 +05301311 } else {
1312 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001313 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 +00001314 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301315 }
1316 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1317 //Examine the MIB Data Sync
1318 // callbacks to be handled:
1319 // Event(ulEvSuccess)
1320 // Event(ulEvTimeout)
1321 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001322 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001323 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001324 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001325 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001326 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001327 }
1328 } else {
divyadesai4d299552020-08-18 07:13:49 +00001329 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001330 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001331 }
1332 return nil
1333}
1334
Himani Chawla6d2ae152020-09-02 13:11:20 +05301335func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001336 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001337 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001338 if dh.deviceReason != drStoppingOpenomci {
divyadesai4d299552020-08-18 07:13:49 +00001339 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001340
mpagenko900ee4b2020-10-12 11:56:34 +00001341 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1342 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1343 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1344 if err := dh.resetFsms(); err != nil {
1345 logger.Errorw("error-updateInterface at FSM stop",
1346 log.Fields{"device-id": dh.deviceID, "error": err})
1347 // abort: system behavior is just unstable ...
1348 return err
1349 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001350 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
mpagenko2418ab02020-11-12 12:58:06 +00001351 _ = dh.deleteDevicePersistencyData() //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001352
1353 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1354 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1355 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301356 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001357 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001358 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001359 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001360 }
mpagenko900ee4b2020-10-12 11:56:34 +00001361 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001362
1363 //TODO!!! remove existing traffic profiles
1364 /* from py code, if TP's exist, remove them - not yet implemented
1365 self._tp = dict()
1366 # Let TP download happen again
1367 for uni_id in self._tp_service_specific_task:
1368 self._tp_service_specific_task[uni_id].clear()
1369 for uni_id in self._tech_profile_download_done:
1370 self._tech_profile_download_done[uni_id].clear()
1371 */
1372
1373 dh.disableUniPortStateUpdate()
1374
mpagenkofc4f56e2020-11-04 17:17:49 +00001375 dh.ReadyForSpecificOmciConfig = false
1376
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001377 if err := dh.deviceReasonUpdate(drStoppingOpenomci, false); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001378 // abort: system behavior is just unstable ...
1379 return err
1380 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001381 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1382 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001383 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1384 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001385 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001386 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001387 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001388 // abort: system behavior is just unstable ...
1389 return err
1390 }
1391 } else {
divyadesai4d299552020-08-18 07:13:49 +00001392 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001393 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001394 return nil
1395}
1396
mpagenko900ee4b2020-10-12 11:56:34 +00001397func (dh *deviceHandler) resetFsms() error {
1398 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1399 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1400 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1401 // and using the stop/reset event should never harm
1402
1403 pDevEntry := dh.getOnuDeviceEntry(false)
1404 if pDevEntry == nil {
1405 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1406 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1407 }
1408
1409 //the MibSync FSM might be active all the ONU-active time,
1410 // hence it must be stopped unconditionally
1411 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1412 if pMibUlFsm != nil {
1413 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1414 }
1415 //MibDownload may run
1416 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1417 if pMibDlFsm != nil {
1418 _ = pMibDlFsm.Event(dlEvReset)
1419 }
1420 //port lock/unlock FSM's may be active
1421 if dh.pUnlockStateFsm != nil {
1422 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1423 }
1424 if dh.pLockStateFsm != nil {
1425 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1426 }
1427 //techProfile related PonAniConfigFsm FSM may be active
1428 if dh.pOnuTP != nil {
1429 // should always be the case here
1430 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1431 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001432 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1433 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1434 }
mpagenko900ee4b2020-10-12 11:56:34 +00001435 }
1436 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001437 // reset the possibly existing VlanConfigFsm
1438 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1439 //VlanFilterFsm exists and was already started
1440 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1441 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001442 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001443 // no need to remove specific data
1444 pVlanFilterFsm.RequestClearPersistency(false)
1445 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001446 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1447 }
1448 }
1449 }
1450 }
1451 //TODO!!! care about PM/Alarm processing once started
1452 return nil
1453}
1454
Himani Chawla6d2ae152020-09-02 13:11:20 +05301455func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001456 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 +05301457
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001458 _ = dh.deviceReasonUpdate(drDiscoveryMibsyncComplete, dh.reconciling)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301459 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenkoa40e99a2020-11-17 13:50:39 +00001460 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301461 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301462 for _, mgmtEntityID := range unigInstKeys {
1463 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1464 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301465 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301466 i++
1467 }
1468 } else {
1469 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1470 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301471 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301472 for _, mgmtEntityID := range veipInstKeys {
1473 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1474 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301475 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301476 i++
1477 }
1478 } else {
1479 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1480 }
1481 if i == 0 {
1482 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1483 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001484 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1485 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1486 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1487 * disable/enable toggling here to allow traffic
1488 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1489 * like the py comment says:
1490 * # start by locking all the unis till mib sync and initial mib is downloaded
1491 * # this way we can capture the port down/up events when we are ready
1492 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301493
mpagenkoa40e99a2020-11-17 13:50:39 +00001494 // Init Uni Ports to Admin locked state
1495 // *** should generate UniLockStateDone event *****
1496 if dh.pLockStateFsm == nil {
1497 dh.createUniLockFsm(true, UniLockStateDone)
1498 } else { //LockStateFSM already init
1499 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
1500 dh.runUniLockFsm(true)
1501 }
1502}
1503
1504func (dh *deviceHandler) processUniLockStateDoneEvent(devEvent OnuDeviceEvent) {
1505 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301506 /* Mib download procedure -
1507 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1508 */
mpagenkoa40e99a2020-11-17 13:50:39 +00001509 pDevEntry := dh.getOnuDeviceEntry(false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301510 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1511 if pMibDlFsm != nil {
1512 if pMibDlFsm.Is(dlStDisabled) {
1513 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001514 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301515 // maybe try a FSM reset and then again ... - TODO!!!
1516 } else {
1517 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1518 // maybe use more specific states here for the specific download steps ...
1519 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001520 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301521 } else {
1522 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1523 //Begin MIB data download (running autonomously)
1524 }
1525 }
1526 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001527 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001528 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301529 // maybe try a FSM reset and then again ... - TODO!!!
1530 }
1531 /***** Mib download started */
1532 } else {
1533 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1534 }
1535}
1536
Himani Chawla6d2ae152020-09-02 13:11:20 +05301537func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001538 logger.Debugw("MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301539 //initiate DevStateUpdate
1540 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001541 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1542 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301543 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1544 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1545 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1546 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1547 } else {
1548 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1549 }
1550 } else {
1551 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1552 log.Fields{"device-id": dh.deviceID})
1553 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001554 _ = dh.deviceReasonUpdate(drInitialMibDownloaded, dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001555 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301556 // *** should generate UniUnlockStateDone event *****
1557 if dh.pUnlockStateFsm == nil {
1558 dh.createUniLockFsm(false, UniUnlockStateDone)
1559 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301560 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301561 dh.runUniLockFsm(false)
1562 }
1563}
1564
Himani Chawla6d2ae152020-09-02 13:11:20 +05301565func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001566 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301567
1568 if !dh.reconciling {
1569 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1570 raisedTs := time.Now().UnixNano()
1571 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1572 } else {
1573 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1574 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301575 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001576 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301577 }
1578}
1579
mpagenko900ee4b2020-10-12 11:56:34 +00001580func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1581 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1582 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1583 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1584 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1585 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1586 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1587 }
1588
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001589 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{"reason": drOmciAdminLock, "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001590 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001591 _ = dh.deviceReasonUpdate(drOmciAdminLock, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001592
1593 //transfer the modified logical uni port state
1594 dh.disableUniPortStateUpdate()
mpagenko900ee4b2020-10-12 11:56:34 +00001595}
1596
1597func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1598 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1599 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1600 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1601 voltha.OperStatus_ACTIVE); err != nil {
1602 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1603 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1604 }
1605
1606 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001607 "reason": drOnuReenabled, "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001608 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001609 _ = dh.deviceReasonUpdate(drOnuReenabled, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001610
1611 //transfer the modified logical uni port state
1612 dh.enableUniPortStateUpdate()
1613}
1614
Himani Chawla6d2ae152020-09-02 13:11:20 +05301615func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001616 if devEvent == OmciAniConfigDone {
1617 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1618 // attention: the device reason update is done based on ONU-UNI-Port related activity
1619 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001620 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001621 // 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 +00001622 _ = dh.deviceReasonUpdate(drTechProfileConfigDownloadSuccess, dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301623 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001624 if dh.reconciling {
1625 go dh.reconcileDeviceFlowConfig()
1626 }
1627 } else { // should be the OmciAniResourceRemoved block
1628 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1629 // attention: the device reason update is done based on ONU-UNI-Port related activity
1630 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001631 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001632 // 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 +00001633 _ = dh.deviceReasonUpdate(drTechProfileConfigDeleteSuccess, false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001634 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001635 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301636}
1637
mpagenkofc4f56e2020-11-04 17:17:49 +00001638func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301639 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001640 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301641 // attention: the device reason update is done based on ONU-UNI-Port related activity
1642 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301643
mpagenkofc4f56e2020-11-04 17:17:49 +00001644 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001645 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001646 // which may be the case from some previous actvity on another UNI Port of the ONU
1647 // or even some previous flow add activity on the same port
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001648 _ = dh.deviceReasonUpdate(drOmciFlowsPushed, dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001649 if dh.reconciling {
1650 go dh.reconcileMetrics()
1651 }
1652 }
1653 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001654 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001655 //not relevant for reconcile
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001656 _ = dh.deviceReasonUpdate(drOmciFlowsDeleted, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001657 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301658 }
1659}
1660
Himani Chawla6d2ae152020-09-02 13:11:20 +05301661//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1662func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301663 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001664 case MibDatabaseSync:
1665 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301666 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001667 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001668 case UniLockStateDone:
1669 {
1670 dh.processUniLockStateDoneEvent(devEvent)
1671 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001672 case MibDownloadDone:
1673 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301674 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001675 }
1676 case UniUnlockStateDone:
1677 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301678 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001679 }
mpagenko900ee4b2020-10-12 11:56:34 +00001680 case UniEnableStateDone:
1681 {
1682 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001683 }
1684 case UniDisableStateDone:
1685 {
1686 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001687 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001688 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001689 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301690 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001691 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001692 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001693 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301694 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001695 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001696 default:
1697 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001698 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001699 }
1700 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001701}
1702
Himani Chawla6d2ae152020-09-02 13:11:20 +05301703func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001704 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301705 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301706 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001707 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301708 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001709 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301710 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301711 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301713 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001714 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001715 //store UniPort with the System-PortNumber key
1716 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001717 if !dh.reconciling {
1718 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301719 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001720 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1721 } //error logging already within UniPort method
1722 } else {
1723 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1724 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001725 }
1726 }
1727}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001728
mpagenko3af1f032020-06-10 08:53:41 +00001729// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301730func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001731 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301732 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001733 // with following remark:
1734 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1735 // # load on the core
1736
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001737 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001738
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001739 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001740 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301741 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001742 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301743 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001744 if !dh.reconciling {
1745 //maybe also use getter functions on uniPort - perhaps later ...
1746 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1747 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001748 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001749 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1750 }
mpagenko3af1f032020-06-10 08:53:41 +00001751 }
1752 }
1753}
1754
1755// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301756func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001757 // compare enableUniPortStateUpdate() above
1758 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1759 for uniNo, uniPort := range dh.uniEntityMap {
1760 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301761 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001762 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301763 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001764 //maybe also use getter functions on uniPort - perhaps later ...
1765 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001766 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001767 }
1768}
1769
1770// ONU_Active/Inactive announcement on system KAFKA bus
1771// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301772func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001773 var de voltha.DeviceEvent
1774 eventContext := make(map[string]string)
1775 //Populating event context
1776 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301777 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001778 if err != nil || parentDevice == nil {
1779 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301780 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001781 }
1782 oltSerialNumber := parentDevice.SerialNumber
1783
1784 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1785 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1786 eventContext["serial-number"] = dh.device.SerialNumber
1787 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301788 eventContext["device_id"] = aDeviceID
1789 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001790 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001791 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001792
1793 /* Populating device event body */
1794 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301795 de.ResourceId = aDeviceID
1796 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001797 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1798 de.Description = fmt.Sprintf("%s Event - %s - %s",
1799 cEventObjectType, cOnuActivatedEvent, "Raised")
1800 } else {
1801 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1802 de.Description = fmt.Sprintf("%s Event - %s - %s",
1803 cEventObjectType, cOnuActivatedEvent, "Cleared")
1804 }
1805 /* Send event to KAFKA */
1806 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1807 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301808 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001809 }
1810 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301811 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001812}
1813
Himani Chawla4d908332020-08-31 12:30:20 +05301814// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301815func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001816 chLSFsm := make(chan Message, 2048)
1817 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301818 if aAdminState {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001819 logger.Debugw("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001820 sFsmName = "LockStateFSM"
1821 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001822 logger.Debugw("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001823 sFsmName = "UnLockStateFSM"
1824 }
mpagenko3af1f032020-06-10 08:53:41 +00001825
Himani Chawla6d2ae152020-09-02 13:11:20 +05301826 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001827 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001828 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001829 return
1830 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301831 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001832 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001833 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301834 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001835 dh.pLockStateFsm = pLSFsm
1836 } else {
1837 dh.pUnlockStateFsm = pLSFsm
1838 }
1839 dh.runUniLockFsm(aAdminState)
1840 } else {
divyadesai4d299552020-08-18 07:13:49 +00001841 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001842 }
1843}
1844
1845// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301846func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001847 /* Uni Port lock/unlock procedure -
1848 ***** should run via 'adminDone' state and generate the argument requested event *****
1849 */
1850 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301851 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001852 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1853 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1854 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001855 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301856 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001857 }
1858 } else {
1859 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1860 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1861 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001862 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301863 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001864 }
1865 }
1866 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001867 if pLSStatemachine.Is(uniStDisabled) {
1868 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001869 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1870 // maybe try a FSM reset and then again ... - TODO!!!
1871 } else {
1872 /***** LockStateFSM started */
1873 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001874 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001875 }
1876 } else {
1877 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001878 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001879 // maybe try a FSM reset and then again ... - TODO!!!
1880 }
1881 } else {
divyadesai4d299552020-08-18 07:13:49 +00001882 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001883 // maybe try a FSM reset and then again ... - TODO!!!
1884 }
1885}
1886
Himani Chawla6d2ae152020-09-02 13:11:20 +05301887//setBackend provides a DB backend for the specified path on the existing KV client
1888func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001889 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1890 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001891 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001892 kvbackend := &db.Backend{
1893 Client: dh.pOpenOnuAc.kvClient,
1894 StoreType: dh.pOpenOnuAc.KVStoreType,
1895 /* address config update acc. to [VOL-2736] */
1896 Address: addr,
1897 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1898 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001899
mpagenkoaf801632020-07-03 10:00:42 +00001900 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001901}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301902func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301903 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001904
mpagenkodff5dda2020-08-28 11:52:01 +00001905 for _, field := range flow.GetOfbFields(apFlowItem) {
1906 switch field.Type {
1907 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1908 {
mpagenko01e726e2020-10-23 09:45:29 +00001909 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001910 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1911 }
mpagenko01e726e2020-10-23 09:45:29 +00001912 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00001913 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1914 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301915 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00001916 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301917 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1918 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001919 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1920 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00001921 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
1922 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301923 return
mpagenkodff5dda2020-08-28 11:52:01 +00001924 }
1925 }
mpagenko01e726e2020-10-23 09:45:29 +00001926 */
mpagenkodff5dda2020-08-28 11:52:01 +00001927 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1928 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301929 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001930 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301931 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001932 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301933 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001934 }
mpagenko01e726e2020-10-23 09:45:29 +00001935 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301936 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001937 }
1938 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1939 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301940 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00001941 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001942 "PCP": loAddPcp})
1943 }
1944 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1945 {
mpagenko01e726e2020-10-23 09:45:29 +00001946 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001947 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1948 }
1949 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1950 {
mpagenko01e726e2020-10-23 09:45:29 +00001951 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001952 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1953 }
1954 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1955 {
mpagenko01e726e2020-10-23 09:45:29 +00001956 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001957 "IPv4-DST": field.GetIpv4Dst()})
1958 }
1959 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1960 {
mpagenko01e726e2020-10-23 09:45:29 +00001961 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001962 "IPv4-SRC": field.GetIpv4Src()})
1963 }
1964 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1965 {
mpagenko01e726e2020-10-23 09:45:29 +00001966 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001967 "Metadata": field.GetTableMetadata()})
1968 }
1969 /*
1970 default:
1971 {
1972 //all other entires ignored
1973 }
1974 */
1975 }
1976 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301977}
mpagenkodff5dda2020-08-28 11:52:01 +00001978
Himani Chawla6d2ae152020-09-02 13:11:20 +05301979func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001980 for _, action := range flow.GetActions(apFlowItem) {
1981 switch action.Type {
1982 /* not used:
1983 case of.OfpActionType_OFPAT_OUTPUT:
1984 {
mpagenko01e726e2020-10-23 09:45:29 +00001985 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001986 "Output": action.GetOutput()})
1987 }
1988 */
1989 case of.OfpActionType_OFPAT_PUSH_VLAN:
1990 {
mpagenko01e726e2020-10-23 09:45:29 +00001991 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001992 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1993 }
1994 case of.OfpActionType_OFPAT_SET_FIELD:
1995 {
1996 pActionSetField := action.GetSetField()
1997 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00001998 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001999 "OxcmClass": pActionSetField.Field.OxmClass})
2000 }
2001 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302002 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002003 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302004 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002005 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302006 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002007 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302008 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002009 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002010 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002011 "Type": pActionSetField.Field.GetOfbField().Type})
2012 }
2013 }
2014 /*
2015 default:
2016 {
2017 //all other entires ignored
2018 }
2019 */
2020 }
2021 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302022}
2023
2024//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302025func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302026 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2027 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2028 var loAddPcp, loSetPcp uint8
2029 var loIPProto uint32
2030 /* the TechProfileId is part of the flow Metadata - compare also comment within
2031 * OLT-Adapter:openolt_flowmgr.go
2032 * Metadata 8 bytes:
2033 * Most Significant 2 Bytes = Inner VLAN
2034 * Next 2 Bytes = Tech Profile ID(TPID)
2035 * Least Significant 4 Bytes = Port ID
2036 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2037 * subscriber related flows.
2038 */
2039
2040 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2041 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002042 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302043 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002044 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302045 }
2046 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002047 loCookie := apFlowItem.GetCookie()
2048 loCookieSlice := []uint64{loCookie}
2049 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2050 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302051
2052 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002053 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302054 if loIPProto == 2 {
2055 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2056 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002057 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2058 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302059 return nil
2060 }
mpagenko01e726e2020-10-23 09:45:29 +00002061 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302062 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002063
2064 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002065 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002066 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2067 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2068 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2069 //TODO!!: Use DeviceId within the error response to rwCore
2070 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002071 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002072 }
2073 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002074 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002075 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2076 } else {
2077 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2078 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2079 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302080 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002081 }
mpagenko01e726e2020-10-23 09:45:29 +00002082 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002083 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302084 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002085 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2086 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002087 }
mpagenko01e726e2020-10-23 09:45:29 +00002088 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002089 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002090}
2091
2092//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2093func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2094 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2095 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2096 //no extra check is done on the rule parameters
2097 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2098 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2099 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2100 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002101 // - 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 +00002102 loCookie := apFlowItem.GetCookie()
2103 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2104
2105 /* TT related temporary workaround - should not be needed anymore
2106 for _, field := range flow.GetOfbFields(apFlowItem) {
2107 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2108 loIPProto := field.GetIpProto()
2109 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2110 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2111 if loIPProto == 2 {
2112 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2113 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2114 log.Fields{"device-id": dh.deviceID})
2115 return nil
2116 }
2117 }
2118 } //for all OfbFields
2119 */
2120
2121 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2122 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2123 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002124 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002125 log.Fields{"device-id": dh.deviceID})
2126 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002127 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2128 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2129
mpagenko01e726e2020-10-23 09:45:29 +00002130 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002131}
2132
Himani Chawla26e555c2020-08-31 12:30:20 +05302133// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002134func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2135 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002136 chVlanFilterFsm := make(chan Message, 2048)
2137
Himani Chawla6d2ae152020-09-02 13:11:20 +05302138 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002139 if pDevEntry == nil {
2140 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302141 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002142 }
2143
2144 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002145 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2146 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002147 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302148 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002149 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2150 if pVlanFilterStatemachine != nil {
2151 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2152 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2153 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302154 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002155 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 /***** UniVlanConfigFsm started */
2157 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2158 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2159 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002160 } else {
2161 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2162 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302163 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002164 }
2165 } else {
2166 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2167 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302168 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002169 }
2170 } else {
2171 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2172 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302173 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002174 }
2175 return nil
2176}
2177
mpagenkofc4f56e2020-11-04 17:17:49 +00002178//VerifyVlanConfigRequest checks on existence of a given uniPort
2179// and starts verification of flow config based on that
2180func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2181 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2182 var pCurrentUniPort *onuUniPort
2183 for _, uniPort := range dh.uniEntityMap {
2184 // only if this port is validated for operState transfer
2185 if uniPort.uniID == uint8(aUniID) {
2186 pCurrentUniPort = uniPort
2187 break //found - end search loop
2188 }
2189 }
2190 if pCurrentUniPort == nil {
2191 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2192 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2193 return
2194 }
2195 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2196}
2197
mpagenkodff5dda2020-08-28 11:52:01 +00002198//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302199func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002200 //TODO!! verify and start pending flow configuration
2201 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2202 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002204 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2205 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2206 if pVlanFilterStatemachine != nil {
2207 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2208 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2209 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2210 } else {
2211 /***** UniVlanConfigFsm continued */
2212 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2213 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2214 "UniPort": apUniPort.portNo})
2215 }
2216 } else {
2217 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2218 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2219 }
2220 } else {
2221 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2222 "device-id": dh.deviceID})
2223 }
2224
2225 } // else: nothing to do
2226}
2227
2228//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2229// 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 +05302230func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002231 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2232 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2233 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302234 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002235}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002236
2237//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2238//available for potential reconcilement
2239
2240func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2241
2242 if dh.reconciling {
2243 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2244 return nil
2245 }
mpagenko2418ab02020-11-12 12:58:06 +00002246 logger.Debugw("Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002247
2248 pDevEntry := dh.getOnuDeviceEntry(true)
2249 if pDevEntry == nil {
2250 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2251 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2252 }
2253 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2254
2255 pDevEntry.lockOnuKVStoreMutex()
2256 defer pDevEntry.unlockOnuKVStoreMutex()
2257
2258 // deadline context to ensure completion of background routines waited for
2259 //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 +05302260 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002261 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2262
2263 pDevEntry.resetKvProcessingErrorIndication()
2264 var wg sync.WaitGroup
2265 wg.Add(1) // for the 1 go routine to finish
2266
2267 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002268 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002269
2270 return pDevEntry.getKvProcessingErrorIndication()
2271}
2272
mpagenko01e726e2020-10-23 09:45:29 +00002273func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002274 defer cancel() //ensure termination of context (may be pro forma)
2275 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002276 logger.Debugw("WaitGroup processing completed", log.Fields{
2277 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002278}
2279
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002280func (dh *deviceHandler) deviceReasonUpdate(deviceReason string, dontNotifyCore bool) error {
2281
2282 dh.deviceReason = deviceReason
2283 if !dontNotifyCore {
2284 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
2285 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, deviceReason); err != nil {
2286 logger.Errorw("DeviceReasonUpdate: error",
2287 log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID, "error": err})
2288 return err
2289 }
2290 logger.Infow("DeviceReasonUpdate: success", log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID})
2291 return nil
2292 }
2293 logger.Infow("Don't notify core about DeviceReasonUpdate", log.Fields{"deviceReason": deviceReason, "device-id": dh.deviceID})
2294 return nil
2295}
2296
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002297func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2298 var errStr string = ""
2299 for _, err := range errS {
2300 if err != nil {
2301 errStr = errStr + err.Error() + " "
2302 }
2303 }
2304 if errStr != "" {
2305 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2306 }
2307 return nil
2308}