blob: f7dad9acefd47adad7fd46e9791a300f85b0083d [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
Himani Chawla6d2ae152020-09-02 13:11:20 +053093//deviceHandler will interact with the ONU ? device.
94type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000095 deviceID string
96 DeviceType string
97 adminState string
98 device *voltha.Device
99 logicalDeviceID string
100 ProxyAddressID string
101 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530102 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000103 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000104
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000105 coreProxy adapterif.CoreProxy
106 AdapterProxy adapterif.AdapterProxy
107 EventProxy adapterif.EventProxy
108
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000109 pOpenOnuAc *OpenONUAC
110 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530111 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000112 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000113 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530114 pOnuTP *onuUniTechProf
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000115 exitChannel chan int
116 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000117 pOnuIndication *oop.OnuIndication
mpagenko3af1f032020-06-10 08:53:41 +0000118 deviceReason string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530119 pLockStateFsm *lockStateFsm
120 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000121
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000122 //flowMgr *OpenOltFlowMgr
123 //eventMgr *OpenOltEventMgr
124 //resourceMgr *rsrcMgr.OpenOltResourceMgr
125
126 //discOnus sync.Map
127 //onus sync.Map
128 //portStats *OpenOltStatisticsMgr
129 //metrics *pmmetrics.PmMetrics
mpagenkodff5dda2020-08-28 11:52:01 +0000130 stopCollector chan bool
131 stopHeartbeatCheck chan bool
132 activePorts sync.Map
Himani Chawla6d2ae152020-09-02 13:11:20 +0530133 uniEntityMap map[uint32]*onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000134 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
135 reconciling bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000136}
137
Himani Chawla6d2ae152020-09-02 13:11:20 +0530138//newDeviceHandler creates a new device handler
139func newDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
140 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000141 dh.coreProxy = cp
142 dh.AdapterProxy = ap
143 dh.EventProxy = ep
144 cloned := (proto.Clone(device)).(*voltha.Device)
145 dh.deviceID = cloned.Id
146 dh.DeviceType = cloned.Type
147 dh.adminState = "up"
148 dh.device = cloned
149 dh.pOpenOnuAc = adapter
150 dh.exitChannel = make(chan int, 1)
151 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000152 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153 dh.stopCollector = make(chan bool, 2)
154 dh.stopHeartbeatCheck = make(chan bool, 2)
155 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
156 dh.activePorts = sync.Map{}
157 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000159 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000160 dh.reconciling = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000161
162 // Device related state machine
163 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000164 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000165 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000166 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
167 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
168 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
169 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
170 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 },
172 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000173 "before_event": func(e *fsm.Event) { dh.logStateChange(e) },
174 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(e) },
175 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(e) },
176 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(e) },
177 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
178 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(e) },
179 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(e) },
180 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000181 },
182 )
mpagenkoaf801632020-07-03 10:00:42 +0000183
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184 return &dh
185}
186
Himani Chawla6d2ae152020-09-02 13:11:20 +0530187// start save the device to the data model
188func (dh *deviceHandler) start(ctx context.Context) {
divyadesai4d299552020-08-18 07:13:49 +0000189 logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 // Add the initial device to the local model
191 logger.Debug("device-handler-started")
192}
193
Himani Chawla4d908332020-08-31 12:30:20 +0530194/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000195// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530196func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197 logger.Debug("stopping-device-handler")
198 dh.exitChannel <- 1
199}
Himani Chawla4d908332020-08-31 12:30:20 +0530200*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201
202// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530203// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204
Himani Chawla6d2ae152020-09-02 13:11:20 +0530205//adoptOrReconcileDevice adopts the OLT device
206func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000207 logger.Debugw("Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000208
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000209 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000210 if dh.pDeviceStateFsm.Is(devStNull) {
211 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000212 logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
213 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000214 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 } else {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000216 logger.Debugw("AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000217 }
218
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219}
220
Himani Chawla6d2ae152020-09-02 13:11:20 +0530221func (dh *deviceHandler) processInterAdapterOMCIReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530222 msgBody := msg.GetBody()
223 omciMsg := &ic.InterAdapterOmciMessage{}
224 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
225 logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
226 "device-id": dh.deviceID, "error": err})
227 return err
228 }
229
230 //assuming omci message content is hex coded!
231 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
232 logger.Debugw("inter-adapter-recv-omci", log.Fields{
233 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
234 //receive_message(omci_msg.message)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530235 pDevEntry := dh.getOnuDeviceEntry(true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530236 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530237 return pDevEntry.PDevOmciCC.receiveMessage(context.TODO(), omciMsg.Message)
Himani Chawla26e555c2020-08-31 12:30:20 +0530238 }
239 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
240 return errors.New("no valid OnuDevice")
241}
242
Himani Chawla6d2ae152020-09-02 13:11:20 +0530243func (dh *deviceHandler) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530244 msgBody := msg.GetBody()
245 onuIndication := &oop.OnuIndication{}
246 if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
247 logger.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{
248 "device-id": dh.deviceID, "error": err})
249 return err
250 }
251
252 onuOperstate := onuIndication.GetOperState()
253 logger.Debugw("inter-adapter-recv-onu-ind", log.Fields{"OnuId": onuIndication.GetOnuId(),
254 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
255 "SNR": onuIndication.GetSerialNumber()})
256
257 //interface related functions might be error checked ....
258 if onuOperstate == "up" {
259 _ = dh.createInterface(onuIndication)
260 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
261 _ = dh.updateInterface(onuIndication)
262 } else {
263 logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
264 return errors.New("invalidOperState")
265 }
266 return nil
267}
268
Himani Chawla6d2ae152020-09-02 13:11:20 +0530269func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530270 msg *ic.InterAdapterMessage) error {
271 if dh.pOnuTP == nil {
272 //should normally not happen ...
273 logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
274 log.Fields{"device-id": dh.deviceID})
275 return errors.New("techProfile DLMsg request while onuTechProf instance not setup")
276 }
277 if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock") {
278 // I've seen cases for this request, where the device was already stopped
279 logger.Warnw("TechProf stopped: device-unreachable", log.Fields{"device-id": dh.deviceID})
280 return errors.New("device-unreachable")
281 }
282
283 msgBody := msg.GetBody()
284 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
285 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
286 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
287 "device-id": dh.deviceID, "error": err})
288 return err
289 }
290
291 // we have to lock access to TechProfile processing based on different messageType calls or
292 // even to fast subsequent calls of the same messageType
293 dh.pOnuTP.lockTpProcMutex()
294 // lock hangs as long as below decoupled or other related TechProfile processing is active
295 if bTpModify := dh.pOnuTP.updateOnuUniTpPath(techProfMsg.UniId, techProfMsg.Path); bTpModify {
296 // if there has been some change for some uni TechProfilePath
297 //in order to allow concurrent calls to other dh instances we do not wait for execution here
298 //but doing so we can not indicate problems to the caller (who does what with that then?)
299 //by now we just assume straightforward successful execution
300 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
301 // possible problems to the caller later autonomously
302
303 // deadline context to ensure completion of background routines waited for
304 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
305 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
306 dctx, cancel := context.WithDeadline(context.Background(), deadline)
307
308 dh.pOnuTP.resetProcessingErrorIndication()
309 var wg sync.WaitGroup
310 wg.Add(2) // for the 2 go routines to finish
311 // attention: deadline completion check and wg.Done is to be done in both routines
312 go dh.pOnuTP.configureUniTp(dctx, uint8(techProfMsg.UniId), techProfMsg.Path, &wg)
313 go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
314 //the wait.. function is responsible for tpProcMutex.Unlock()
315 err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //wait for background process to finish and collect their result
316 return err
317 }
318 // no change, nothing really to do
319 dh.pOnuTP.unlockTpProcMutex()
320 //return success
321 return nil
322}
323
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530325 msg *ic.InterAdapterMessage) error {
326
327 if dh.pOnuTP == nil {
328 //should normally not happen ...
329 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
330 log.Fields{"device-id": dh.deviceID})
331 return errors.New("techProfile DelGem request while onuTechProf instance not setup")
332 }
333
334 msgBody := msg.GetBody()
335 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
336 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
337 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
338 "device-id": dh.deviceID, "error": err})
339 return err
340 }
341
342 //compare TECH_PROFILE_DOWNLOAD_REQUEST
343 dh.pOnuTP.lockTpProcMutex()
344
345 // deadline context to ensure completion of background routines waited for
346 deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
347 dctx, cancel := context.WithDeadline(context.Background(), deadline)
348
349 dh.pOnuTP.resetProcessingErrorIndication()
350 var wg sync.WaitGroup
351 wg.Add(1) // for the 1 go routine to finish
352 go dh.pOnuTP.deleteTpResource(dctx, delGemPortMsg.UniId, delGemPortMsg.TpPath,
353 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
354 //the wait.. function is responsible for tpProcMutex.Unlock()
355 err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
356 return err
357}
358
Himani Chawla6d2ae152020-09-02 13:11:20 +0530359func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 msg *ic.InterAdapterMessage) error {
361 if dh.pOnuTP == nil {
362 //should normally not happen ...
363 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
364 log.Fields{"device-id": dh.deviceID})
365 return errors.New("techProfile DelTcont request while onuTechProf instance not setup")
366 }
367
368 msgBody := msg.GetBody()
369 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
370 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
371 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
372 "device-id": dh.deviceID, "error": err})
373 return err
374 }
375
376 //compare TECH_PROFILE_DOWNLOAD_REQUEST
377 dh.pOnuTP.lockTpProcMutex()
378 if bTpModify := dh.pOnuTP.updateOnuUniTpPath(delTcontMsg.UniId, ""); bTpModify {
379 // deadline context to ensure completion of background routines waited for
380 deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
381 dctx, cancel := context.WithDeadline(context.Background(), deadline)
382
383 dh.pOnuTP.resetProcessingErrorIndication()
384 var wg sync.WaitGroup
385 wg.Add(2) // for the 2 go routines to finish
386 go dh.pOnuTP.deleteTpResource(dctx, delTcontMsg.UniId, delTcontMsg.TpPath,
387 cResourceTcont, delTcontMsg.AllocId, &wg)
388 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
389 go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
390 //the wait.. function is responsible for tpProcMutex.Unlock()
391 err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
392 return err
393 }
394 dh.pOnuTP.unlockTpProcMutex()
395 //return success
396 return nil
397}
398
Himani Chawla6d2ae152020-09-02 13:11:20 +0530399//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000400// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
401// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530402func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000403 msgID := msg.Header.Id
404 msgType := msg.Header.Type
405 fromTopic := msg.Header.FromTopic
406 toTopic := msg.Header.ToTopic
407 toDeviceID := msg.Header.ToDeviceId
408 proxyDeviceID := msg.Header.ProxyDeviceId
409 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
410 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
411
412 switch msgType {
413 case ic.InterAdapterMessageType_OMCI_REQUEST:
414 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000416 }
417 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
418 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000420 }
mpagenkoaf801632020-07-03 10:00:42 +0000421 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
422 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530423 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000424 }
425 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
426 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530427 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000428
mpagenkoaf801632020-07-03 10:00:42 +0000429 }
430 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
431 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530432 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000433 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000434 default:
435 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000436 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000437 "device-id": dh.deviceID, "msgType": msg.Header.Type})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000438 return errors.New("unimplemented")
439 }
440 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000441}
442
mpagenkodff5dda2020-08-28 11:52:01 +0000443//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530444func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000445 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
446
447 //Remove flows
448 if apOfFlowChanges.ToRemove != nil {
449 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
450 logger.Debugw("incremental flow item remove", log.Fields{"deviceId": dh.deviceID,
451 "Item": flowItem})
452 }
453 }
454 if apOfFlowChanges.ToAdd != nil {
455 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
456 if flowItem.GetCookie() == 0 {
457 logger.Debugw("incremental flow add - no cookie - ignore", log.Fields{
458 "deviceId": dh.deviceID})
459 continue
460 }
461 flowInPort := flow.GetInPort(flowItem)
462 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
463 logger.Errorw("flow inPort invalid", log.Fields{"deviceID": dh.deviceID})
464 return errors.New("flow inPort invalid")
465 } else if flowInPort == dh.ponPortNumber {
466 //this is some downstream flow
467 logger.Debugw("incremental flow ignore downstream", log.Fields{
468 "deviceId": dh.deviceID, "inPort": flowInPort})
469 continue
470 } else {
471 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530472 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000473 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
474 loUniPort = uniPort
475 } else {
476 logger.Errorw("flow inPort not found in UniPorts",
477 log.Fields{"deviceID": dh.deviceID, "inPort": flowInPort})
478 return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
479 }
480 flowOutPort := flow.GetOutPort(flowItem)
481 logger.Debugw("incremental flow-add port indications", log.Fields{
482 "deviceId": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
483 "uniPortName": loUniPort.name})
484 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
485 //abort processing in error case
486 if err != nil {
487 return err
488 }
489 }
490 }
491 }
492 return nil
493}
494
Himani Chawla6d2ae152020-09-02 13:11:20 +0530495//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenko3af1f032020-06-10 08:53:41 +0000496// TODO!!! Clarify usage of this method, it is for sure not used within ONOS (OLT) device disable
497// maybe it is obsolete by now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530498func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000499 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000500
mpagenko3af1f032020-06-10 08:53:41 +0000501 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly - inblock
502 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
503 if dh.deviceReason != "omci-admin-lock" {
504 // disable UNI ports/ONU
505 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
506 // here the result of the processing is not checked (trusted in background) *****
507 if dh.pLockStateFsm == nil {
508 dh.createUniLockFsm(true, UniAdminStateDone)
509 } else { //LockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +0530510 dh.pLockStateFsm.setSuccessEvent(UniAdminStateDone)
mpagenko3af1f032020-06-10 08:53:41 +0000511 dh.runUniLockFsm(true)
512 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300513
mpagenko3af1f032020-06-10 08:53:41 +0000514 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000515 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000516 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +0000517 }
518 dh.deviceReason = "omci-admin-lock"
519 //200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
520 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
521 voltha.OperStatus_UNKNOWN); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000522 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000523 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +0000524 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300525 }
526}
527
Himani Chawla6d2ae152020-09-02 13:11:20 +0530528//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530529func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000530 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000531
532 // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...(like python code)
ozgecanetsiafce57b12020-05-25 14:39:35 +0300533 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
534 voltha.OperStatus_ACTIVE); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000535 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000536 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300537 }
538
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000539 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
540 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000541 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000542 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300543 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000544 dh.deviceReason = "onu-reenabled"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000545
546 // enable ONU/UNI ports
547 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
548 // here the result of the processing is not checked (trusted in background) *****
549 if dh.pUnlockStateFsm == nil {
550 dh.createUniLockFsm(false, UniAdminStateDone)
551 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +0530552 dh.pUnlockStateFsm.setSuccessEvent(UniAdminStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000553 dh.runUniLockFsm(false)
554 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300555}
556
Himani Chawla6d2ae152020-09-02 13:11:20 +0530557func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000558 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
559
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000560 if err := dh.pOnuTP.restoreFromOnuTpPathKvStore(context.TODO()); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000561 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
562 dh.reconciling = false
563 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000564 }
Himani Chawla4d908332020-08-31 12:30:20 +0530565 var onuIndication oop.OnuIndication
566 onuIndication.IntfId = dh.pOnuTP.sOnuPersistentData.PersIntfID
567 onuIndication.OnuId = dh.pOnuTP.sOnuPersistentData.PersOnuID
568 onuIndication.OperState = dh.pOnuTP.sOnuPersistentData.PersOperState
569 onuIndication.AdminState = dh.pOnuTP.sOnuPersistentData.PersAdminState
570 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000571}
572
Himani Chawla6d2ae152020-09-02 13:11:20 +0530573func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000574 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
575
576 dh.pOnuTP.lockTpProcMutex()
577 // lock hangs as long as below decoupled or other related TechProfile processing is active
578 for _, uniData := range dh.pOnuTP.sOnuPersistentData.PersUniTpPath {
579 //In order to allow concurrent calls to other dh instances we do not wait for execution here
580 //but doing so we can not indicate problems to the caller (who does what with that then?)
581 //by now we just assume straightforward successful execution
582 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
583 // possible problems to the caller later autonomously
584
585 // deadline context to ensure completion of background routines waited for
586 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
587 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
588 dctx, cancel := context.WithDeadline(context.Background(), deadline)
589
590 dh.pOnuTP.resetProcessingErrorIndication()
591 var wg sync.WaitGroup
592 wg.Add(1) // for the 1 go routines to finish
593 // attention: deadline completion check and wg.Done is to be done in both routines
Himani Chawla26e555c2020-08-31 12:30:20 +0530594 go dh.pOnuTP.configureUniTp(dctx, uint8(uniData.PersUniID), uniData.PersTpPath, &wg)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000595 //the wait.. function is responsible for tpProcMutex.Unlock()
Himani Chawla4d908332020-08-31 12:30:20 +0530596 _ = dh.pOnuTP.waitForTpCompletion(cancel, &wg) //wait for background process to finish and collect their result
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000597 return
598 }
599 dh.pOnuTP.unlockTpProcMutex()
600 //TODO: reset of reconciling-flag has always to be done in the last ReconcileDevice*() function
601 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000602}
603
Himani Chawla6d2ae152020-09-02 13:11:20 +0530604func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000605 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000606 if err := dh.pOnuTP.deleteOnuTpPathKvStore(context.TODO()); err != nil {
607 return err
608 }
609 // TODO: further actions - stop metrics and FSMs, remove device ...
610 return nil
611}
612
Himani Chawla6d2ae152020-09-02 13:11:20 +0530613func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000614 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300615 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000616 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300617 return errors.New("device-unreachable")
618 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530619 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530620 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
621 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
622 return err
623 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300624 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
625 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000626 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000627 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300628 return err
629 }
630 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting-onu"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000631 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000632 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300633 return err
634 }
635 dh.deviceReason = "rebooting-onu"
636 return nil
637}
638
Himani Chawla6d2ae152020-09-02 13:11:20 +0530639// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000640// #####################################################################################
641
642// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530643// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000644
Himani Chawla6d2ae152020-09-02 13:11:20 +0530645func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000646 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})
647}
648
649// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530650func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000651
652 logger.Debug("doStateInit-started")
653 var err error
654
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000655 // populate what we know. rest comes later after mib sync
656 dh.device.Root = false
657 dh.device.Vendor = "OpenONU"
658 dh.device.Model = "go"
659 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000660 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000661
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000662 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000663
664 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530665 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000666 } else {
667 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
668 log.Fields{"device-id": dh.deviceID})
669 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000670
Himani Chawla4d908332020-08-31 12:30:20 +0530671 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000672 dh.ponPortNumber = dh.device.ParentPortNo
673
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000674 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
675 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
676 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000677 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000678 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530679 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000680
681 /*
682 self._pon = PonPort.create(self, self._pon_port_number)
683 self._pon.add_peer(self.parent_id, self._pon_port_number)
684 self.logger.debug('adding-pon-port-to-agent',
685 type=self._pon.get_port().type,
686 admin_state=self._pon.get_port().admin_state,
687 oper_status=self._pon.get_port().oper_status,
688 )
689 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000690 if !dh.reconciling {
691 logger.Debugw("adding-pon-port", log.Fields{"deviceID": dh.deviceID, "ponPortNo": dh.ponPortNumber})
692 var ponPortNo uint32 = 1
693 if dh.ponPortNumber != 0 {
694 ponPortNo = dh.ponPortNumber
695 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000696
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000697 pPonPort := &voltha.Port{
698 PortNo: ponPortNo,
699 Label: fmt.Sprintf("pon-%d", ponPortNo),
700 Type: voltha.Port_PON_ONU,
701 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530702 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000703 PortNo: ponPortNo}}, // Peer port is parent's port number
704 }
705 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
706 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
707 e.Cancel(err)
708 return
709 }
710 } else {
711 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000712 }
713 logger.Debug("doStateInit-done")
714}
715
716// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530717func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000718
719 logger.Debug("postInit-started")
720 var err error
721 /*
722 dh.Client = oop.NewOpenoltClient(dh.clientCon)
723 dh.pTransitionMap.Handle(ctx, GrpcConnected)
724 return nil
725 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530726 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
727 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000728 e.Cancel(err)
729 return
730 }
731
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000732 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530733 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000734 // reconcilement will be continued after mib download is done
735 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000736 /*
737 ############################################################################
738 # Setup Alarm handler
739 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
740 device.serial_number)
741 ############################################################################
742 # Setup PM configuration for this device
743 # Pass in ONU specific options
744 kwargs = {
745 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
746 'heartbeat': self.heartbeat,
747 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
748 }
749 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
750 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
751 self.logical_device_id, device.serial_number,
752 grouped=True, freq_override=False, **kwargs)
753 pm_config = self._pm_metrics.make_proto()
754 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
755 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
756 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
757
758 # Note, ONU ID and UNI intf set in add_uni_port method
759 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
760 ani_ports=[self._pon])
761
762 # Code to Run OMCI Test Action
763 kwargs_omci_test_action = {
764 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
765 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
766 }
767 serial_number = device.serial_number
768 self._test_request = OmciTestRequest(self.core_proxy,
769 self.omci_agent, self.device_id,
770 AniG, serial_number,
771 self.logical_device_id,
772 exclusive=False,
773 **kwargs_omci_test_action)
774
775 self.enabled = True
776 else:
777 self.logger.info('onu-already-activated')
778 */
779 logger.Debug("postInit-done")
780}
781
782// doStateConnected get the device info and update to voltha core
783// for comparison of the original method (not that easy to uncomment): compare here:
784// voltha-openolt-adapter/adaptercore/device_handler.go
785// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530786func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000787
788 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530789 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000790 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000791 logger.Debug("doStateConnected-done")
792}
793
794// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530795func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000796
797 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530798 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000799 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000800 logger.Debug("doStateUp-done")
801
802 /*
803 // Synchronous call to update device state - this method is run in its own go routine
804 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
805 voltha.OperStatus_ACTIVE); err != nil {
806 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
807 return err
808 }
809 return nil
810 */
811}
812
813// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +0530814func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000815
816 logger.Debug("doStateDown-started")
817 var err error
818
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000819 device := dh.device
820 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000821 /*TODO: needs to handle error scenarios */
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000822 logger.Error("Failed to fetch handler device")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000823 e.Cancel(err)
824 return
825 }
826
827 cloned := proto.Clone(device).(*voltha.Device)
828 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
829 /*
830 // Update the all ports state on that device to disable
831 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
832 logger.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
833 return er
834 }
835
836 //Update the device oper state and connection status
837 cloned.OperStatus = voltha.OperStatus_UNKNOWN
838 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
839 dh.device = cloned
840
841 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
842 logger.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
843 return er
844 }
845
846 //get the child device for the parent device
847 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
848 if err != nil {
849 logger.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
850 return err
851 }
852 for _, onuDevice := range onuDevices.Items {
853
854 // Update onu state as down in onu adapter
855 onuInd := oop.OnuIndication{}
856 onuInd.OperState = "down"
857 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
858 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
859 if er != nil {
860 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
861 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
862 //Do not return here and continue to process other ONUs
863 }
864 }
865 // * Discovered ONUs entries need to be cleared , since after OLT
866 // is up, it starts sending discovery indications again* /
867 dh.discOnus = sync.Map{}
868 logger.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
869 return nil
870 */
Himani Chawla4d908332020-08-31 12:30:20 +0530871 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000872 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000873 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000874}
875
Himani Chawla6d2ae152020-09-02 13:11:20 +0530876// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000877// #################################################################################
878
879// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530880// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000881
Himani Chawla6d2ae152020-09-02 13:11:20 +0530882//getOnuDeviceEntry getsthe ONU device entry and may wait until its value is defined
883func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +0000884 dh.lockDevice.RLock()
885 pOnuDeviceEntry := dh.pOnuOmciDevice
886 if aWait && pOnuDeviceEntry == nil {
887 //keep the read sema short to allow for subsequent write
888 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +0000889 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000890 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
891 // so it might be needed to wait here for that event with some timeout
892 select {
893 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +0000894 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000895 return nil
896 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +0000897 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000898 // if written now, we can return the written value without sema
899 return dh.pOnuOmciDevice
900 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000901 }
mpagenko3af1f032020-06-10 08:53:41 +0000902 dh.lockDevice.RUnlock()
903 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000904}
905
Himani Chawla6d2ae152020-09-02 13:11:20 +0530906//setOnuDeviceEntry sets the ONU device entry within the handler
907func (dh *deviceHandler) setOnuDeviceEntry(
908 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000909 dh.lockDevice.Lock()
910 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +0000911 dh.pOnuOmciDevice = apDeviceEntry
912 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000913}
914
Himani Chawla6d2ae152020-09-02 13:11:20 +0530915//addOnuDeviceEntry creates a new ONU device or returns the existing
916func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +0000917 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000918
Himani Chawla6d2ae152020-09-02 13:11:20 +0530919 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000920 if deviceEntry == nil {
921 /* costum_me_map in python code seems always to be None,
922 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
923 /* also no 'clock' argument - usage open ...*/
924 /* and no alarm_db yet (oo.alarm_db) */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530925 deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
mpagenkoaf801632020-07-03 10:00:42 +0000926 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000927 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000928 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
Himani Chawla6d2ae152020-09-02 13:11:20 +0530929 onuTechProfProc := newOnuUniTechProf(ctx, dh.deviceID, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000930 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +0530931 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +0000932 // fire deviceEntry ready event to spread to possibly waiting processing
933 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +0000934 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000935 } else {
divyadesai4d299552020-08-18 07:13:49 +0000936 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000937 }
938 // might be updated with some error handling !!!
939 return nil
940}
941
942// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530943func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000944 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
945 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
946
947 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000948
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000949 if !dh.reconciling {
950 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
951 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
952 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
953 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
954 }
955 } else {
956 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
957 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000958 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000959 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
960 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
961 // 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 +0000962 // 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 +0000963 // so let's just try to keep it simple ...
964 /*
965 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
966 if err != nil || device == nil {
967 //TODO: needs to handle error scenarios
968 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
969 return errors.New("Voltha Device not found")
970 }
971 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000972
Himani Chawla6d2ae152020-09-02 13:11:20 +0530973 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +0000974 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530975 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530976 return err
977 }
mpagenko3af1f032020-06-10 08:53:41 +0000978 } else {
divyadesai4d299552020-08-18 07:13:49 +0000979 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530980 return errors.New("no valid OnuDevice")
mpagenko3af1f032020-06-10 08:53:41 +0000981 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000982 if !dh.reconciling {
983 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
984 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
985 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
986 }
987 } else {
988 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
989 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000990 }
mpagenko3af1f032020-06-10 08:53:41 +0000991 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000992
993 /* this might be a good time for Omci Verify message? */
994 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530995 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +0000996 dh.device.Id, pDevEntry.PDevOmciCC,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997 true, true) //eclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530998 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000999
1000 /* give the handler some time here to wait for the OMCi verification result
1001 after Timeout start and try MibUpload FSM anyway
1002 (to prevent stopping on just not supported OMCI verification from ONU) */
1003 select {
1004 case <-time.After(2 * time.Second):
1005 logger.Warn("omci start-verification timed out (continue normal)")
1006 case testresult := <-verifyExec:
1007 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1008 }
1009
1010 /* In py code it looks earlier (on activate ..)
1011 # Code to Run OMCI Test Action
1012 kwargs_omci_test_action = {
1013 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1014 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1015 }
1016 serial_number = device.serial_number
1017 self._test_request = OmciTestRequest(self.core_proxy,
1018 self.omci_agent, self.device_id,
1019 AniG, serial_number,
1020 self.logical_device_id,
1021 exclusive=False,
1022 **kwargs_omci_test_action)
1023 ...
1024 # Start test requests after a brief pause
1025 if not self._test_request_started:
1026 self._test_request_started = True
1027 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1028 reactor.callLater(tststart, self._test_request.start_collector)
1029
1030 */
1031 /* which is then: in omci_test_request.py : */
1032 /*
1033 def start_collector(self, callback=None):
1034 """
1035 Start the collection loop for an adapter if the frequency > 0
1036
1037 :param callback: (callable) Function to call to collect PM data
1038 """
1039 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1040 if callback is None:
1041 callback = self.perform_test_omci
1042
1043 if self.lc is None:
1044 self.lc = LoopingCall(callback)
1045
1046 if self.default_freq > 0:
1047 self.lc.start(interval=self.default_freq / 10)
1048
1049 def perform_test_omci(self):
1050 """
1051 Perform the initial test request
1052 """
1053 ani_g_entities = self._device.configuration.ani_g_entities
1054 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1055 is not None else None
1056 self._entity_id = ani_g_entities_ids[0]
1057 self.logger.info('perform-test', entity_class=self._entity_class,
1058 entity_id=self._entity_id)
1059 try:
1060 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1061 result = yield self._device.omci_cc.send(frame)
1062 if not result.fields['omci_message'].fields['success_code']:
1063 self.logger.info('Self-Test Submitted Successfully',
1064 code=result.fields[
1065 'omci_message'].fields['success_code'])
1066 else:
1067 raise TestFailure('Test Failure: {}'.format(
1068 result.fields['omci_message'].fields['success_code']))
1069 except TimeoutError as e:
1070 self.deferred.errback(failure.Failure(e))
1071
1072 except Exception as e:
1073 self.logger.exception('perform-test-Error', e=e,
1074 class_id=self._entity_class,
1075 entity_id=self._entity_id)
1076 self.deferred.errback(failure.Failure(e))
1077
1078 */
1079
1080 // PM related heartbeat??? !!!TODO....
1081 //self._heartbeat.enabled = True
1082
mpagenko1cc3cb42020-07-27 15:24:38 +00001083 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1084 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1085 * 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 +05301086 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001087 */
1088 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001089 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001090 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001091 if pMibUlFsm.Is(ulStDisabled) {
1092 if err := pMibUlFsm.Event(ulEvStart); err != nil {
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001093 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"err": err})
Himani Chawla4d908332020-08-31 12:30:20 +05301094 return errors.New("can't go to state starting")
1095 }
1096 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1097 //Determine ONU status and start/re-start MIB Synchronization tasks
1098 //Determine if this ONU has ever synchronized
1099 if true { //TODO: insert valid check
1100 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
1101 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"err": err})
1102 return errors.New("can't go to state resetting_mib")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001103 }
Himani Chawla4d908332020-08-31 12:30:20 +05301104 } else {
1105 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
1106 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"err": err})
1107 return errors.New("can't go to examine_mds")
1108 }
1109 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1110 //Examine the MIB Data Sync
1111 // callbacks to be handled:
1112 // Event(ulEvSuccess)
1113 // Event(ulEvTimeout)
1114 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001116 } else {
1117 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current())})
1118 return errors.New("wrong state of MibSyncFsm")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119 }
1120 } else {
divyadesai4d299552020-08-18 07:13:49 +00001121 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001122 return errors.New("cannot execut MibSync")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001123 }
1124 return nil
1125}
1126
Himani Chawla6d2ae152020-09-02 13:11:20 +05301127func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001128 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1129 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001130 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001131 //stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
Himani Chawla6d2ae152020-09-02 13:11:20 +05301132 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001133 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001134 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301135 return errors.New("no valid OnuDevice")
mpagenko3af1f032020-06-10 08:53:41 +00001136 }
1137
1138 switch dh.deviceReason {
1139 case "starting-openomci":
1140 { //MIBSync FSM may run
1141 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1142 if pMibUlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301143 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
mpagenko3af1f032020-06-10 08:53:41 +00001144 }
1145 }
1146 case "discovery-mibsync-complete":
1147 { //MibDownload may run
1148 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1149 if pMibDlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301150 _ = pMibDlFsm.Event(dlEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001151 }
1152 }
1153 default:
mpagenko3dbcdd22020-07-22 07:38:45 +00001154 {
1155 //port lock/unlock FSM's may be active
mpagenko3af1f032020-06-10 08:53:41 +00001156 if dh.pUnlockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301157 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001158 }
1159 if dh.pLockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301160 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001161 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001162 //techProfile related PonAniConfigFsm FSM may be active
1163 // maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1164 if dh.pOnuTP.pAniConfigFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301165 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +00001166 }
mpagenkodff5dda2020-08-28 11:52:01 +00001167 for _, uniPort := range dh.uniEntityMap {
1168 //reset the TechProfileConfig Done state for all (active) UNI's
Himani Chawla26e555c2020-08-31 12:30:20 +05301169 dh.pOnuTP.setConfigDone(uniPort.uniID, false)
1170 // reset the possibly existing VlanConfigFsm
1171 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00001172 //VlanFilterFsm exists and was already started
1173 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1174 if pVlanFilterStatemachine != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301175 _ = pVlanFilterStatemachine.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +00001176 }
1177 }
1178 }
mpagenko3af1f032020-06-10 08:53:41 +00001179 }
1180 //TODO!!! care about PM/Alarm processing once started
1181 }
1182 //TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
Himani Chawla4d908332020-08-31 12:30:20 +05301183 // (mainly the still separate 'Event states')
mpagenko3af1f032020-06-10 08:53:41 +00001184 // so it is questionable, how this is resolved after some possible re-enable
1185 // assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
1186
1187 //stop/remove(?) the device entry
Himani Chawla6d2ae152020-09-02 13:11:20 +05301188 _ = pDevEntry.stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
mpagenko3af1f032020-06-10 08:53:41 +00001189
1190 //TODO!!! remove existing traffic profiles
1191 /* from py code, if TP's exist, remove them - not yet implemented
1192 self._tp = dict()
1193 # Let TP download happen again
1194 for uni_id in self._tp_service_specific_task:
1195 self._tp_service_specific_task[uni_id].clear()
1196 for uni_id in self._tech_profile_download_done:
1197 self._tech_profile_download_done[uni_id].clear()
1198 */
1199
1200 dh.disableUniPortStateUpdate()
1201
1202 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001203 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001204 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001205 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001206 // abort: system behavior is just unstable ...
1207 return err
1208 }
1209 dh.deviceReason = "stopping-openomci"
1210
1211 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1212 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001213 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001214 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001215 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001216 // abort: system behavior is just unstable ...
1217 return err
1218 }
1219 } else {
divyadesai4d299552020-08-18 07:13:49 +00001220 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001221 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001222 return nil
1223}
1224
Himani Chawla6d2ae152020-09-02 13:11:20 +05301225func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301226 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1227 if !dh.reconciling {
1228 //initiate DevStateUpdate
1229 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1230 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1231 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
1232 "device-id": dh.deviceID, "error": err})
1233 } else {
1234 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
1235 }
1236 } else {
1237 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1238 log.Fields{"device-id": dh.deviceID})
1239 }
1240 //set internal state anyway - as it was done
1241 dh.deviceReason = "discovery-mibsync-complete"
1242
1243 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301244 pDevEntry := dh.getOnuDeviceEntry(false)
1245 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301246 for _, mgmtEntityID := range unigInstKeys {
1247 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1248 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301249 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301250 i++
1251 }
1252 } else {
1253 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1254 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301255 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301256 for _, mgmtEntityID := range veipInstKeys {
1257 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1258 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301259 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301260 i++
1261 }
1262 } else {
1263 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1264 }
1265 if i == 0 {
1266 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1267 }
1268
1269 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1270 * left the code here as comment in case such processing should prove needed unexpectedly
1271 // Init Uni Ports to Admin locked state
1272 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1273 // *** should generate UniLockStateDone event *****
1274 if dh.pLockStateFsm == nil {
1275 dh.createUniLockFsm(true, UniLockStateDone)
1276 } else { //LockStateFSM already init
1277 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1278 dh.runUniLockFsm(true)
1279 }
1280 }
1281 case UniLockStateDone:
1282 {
1283 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1284 * lockState processing commented out
1285 */
1286 /* Mib download procedure -
1287 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1288 */
1289 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1290 if pMibDlFsm != nil {
1291 if pMibDlFsm.Is(dlStDisabled) {
1292 if err := pMibDlFsm.Event(dlEvStart); err != nil {
1293 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"err": err})
1294 // maybe try a FSM reset and then again ... - TODO!!!
1295 } else {
1296 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1297 // maybe use more specific states here for the specific download steps ...
1298 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
1299 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"err": err})
1300 } else {
1301 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1302 //Begin MIB data download (running autonomously)
1303 }
1304 }
1305 } else {
1306 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current())})
1307 // maybe try a FSM reset and then again ... - TODO!!!
1308 }
1309 /***** Mib download started */
1310 } else {
1311 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1312 }
1313}
1314
Himani Chawla6d2ae152020-09-02 13:11:20 +05301315func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301316 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1317 //initiate DevStateUpdate
1318 if !dh.reconciling {
1319 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1320 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1321 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1322 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1323 } else {
1324 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1325 }
1326 } else {
1327 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1328 log.Fields{"device-id": dh.deviceID})
1329 }
1330 if !dh.reconciling {
1331 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1332 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1333 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
1334 log.Fields{"device-id": dh.deviceID, "error": err})
1335 } else {
1336 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
1337 }
1338 } else {
1339 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1340 log.Fields{"device-id": dh.deviceID})
1341 }
1342 //set internal state anyway - as it was done
1343 dh.deviceReason = "initial-mib-downloaded"
1344 // *** should generate UniUnlockStateDone event *****
1345 if dh.pUnlockStateFsm == nil {
1346 dh.createUniLockFsm(false, UniUnlockStateDone)
1347 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301348 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301349 dh.runUniLockFsm(false)
1350 }
1351}
1352
Himani Chawla6d2ae152020-09-02 13:11:20 +05301353func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301354 go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
1355
1356 if !dh.reconciling {
1357 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1358 raisedTs := time.Now().UnixNano()
1359 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1360 } else {
1361 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1362 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301363 go dh.reconcileDeviceTechProf()
Himani Chawla26e555c2020-08-31 12:30:20 +05301364 //TODO: further actions e.g. restore flows, metrics, ...
1365 }
1366}
1367
Himani Chawla6d2ae152020-09-02 13:11:20 +05301368func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301369 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1370 // attention: the device reason update is done based on ONU-UNI-Port related activity
1371 // - which may cause some inconsistency
1372 if dh.deviceReason != "tech-profile-config-download-success" {
1373 // which may be the case from some previous actvity on another UNI Port of the ONU
1374 if !dh.reconciling {
1375 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1376 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1377 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
1378 log.Fields{"device-id": dh.deviceID, "error": err})
1379 } else {
1380 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
1381 log.Fields{"device-id": dh.deviceID})
1382 }
1383 } else {
1384 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
1385 log.Fields{"device-id": dh.deviceID})
1386 }
1387 //set internal state anyway - as it was done
1388 dh.deviceReason = "tech-profile-config-download-success"
1389 }
1390}
1391
Himani Chawla6d2ae152020-09-02 13:11:20 +05301392func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301393 logger.Debugw("OmciVlanFilterDone event received",
1394 log.Fields{"device-id": dh.deviceID})
1395 // attention: the device reason update is done based on ONU-UNI-Port related activity
1396 // - which may cause some inconsistency
1397 // yield self.core_proxy.device_reason_update(self.device_id, 'omci-flows-pushed')
1398
1399 if dh.deviceReason != "omci-flows-pushed" {
1400 // which may be the case from some previous actvity on another UNI Port of the ONU
1401 // or even some previous flow add activity on the same port
1402 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1403 logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
1404 log.Fields{"device-id": dh.deviceID, "error": err})
1405 } else {
1406 logger.Infow("updated dev reason to ''omci-flows-pushed'",
1407 log.Fields{"device-id": dh.deviceID})
1408 }
1409 //set internal state anyway - as it was done
1410 dh.deviceReason = "omci-flows-pushed"
1411 }
1412}
1413
Himani Chawla6d2ae152020-09-02 13:11:20 +05301414//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1415func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301416 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001417 case MibDatabaseSync:
1418 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301419 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001420 }
1421 case MibDownloadDone:
1422 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301423 dh.processMibDownloadDoneEvent(devEvent)
1424
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001425 }
1426 case UniUnlockStateDone:
1427 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301428 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001429
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001430 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001431 case OmciAniConfigDone:
1432 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301433 dh.processOmciAniConfigDoneEvent(devEvent)
1434
mpagenko3dbcdd22020-07-22 07:38:45 +00001435 }
mpagenkodff5dda2020-08-28 11:52:01 +00001436 case OmciVlanFilterDone:
1437 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301438 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001439
mpagenkodff5dda2020-08-28 11:52:01 +00001440 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001441 default:
1442 {
Himani Chawla4d908332020-08-31 12:30:20 +05301443 logger.Warnw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001444 }
1445 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001446}
1447
Himani Chawla6d2ae152020-09-02 13:11:20 +05301448func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001449 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301450 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301451 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001452 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301453 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001454 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301455 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301456 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001457 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301458 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001460 //store UniPort with the System-PortNumber key
1461 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001462 if !dh.reconciling {
1463 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301464 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001465 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1466 } //error logging already within UniPort method
1467 } else {
1468 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1469 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001470 }
1471 }
1472}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001473
mpagenko3af1f032020-06-10 08:53:41 +00001474// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301475func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001476 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301477 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001478 // with following remark:
1479 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1480 // # load on the core
1481
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001482 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001483
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001484 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001485 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301486 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001487 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301488 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001489 if !dh.reconciling {
1490 //maybe also use getter functions on uniPort - perhaps later ...
1491 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1492 } else {
1493 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1494 }
mpagenko3af1f032020-06-10 08:53:41 +00001495 }
1496 }
1497}
1498
1499// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301500func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001501 // compare enableUniPortStateUpdate() above
1502 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1503 for uniNo, uniPort := range dh.uniEntityMap {
1504 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301505 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001506 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301507 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001508 //maybe also use getter functions on uniPort - perhaps later ...
1509 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001510 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001511 }
1512}
1513
1514// ONU_Active/Inactive announcement on system KAFKA bus
1515// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301516func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001517 var de voltha.DeviceEvent
1518 eventContext := make(map[string]string)
1519 //Populating event context
1520 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301521 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001522 if err != nil || parentDevice == nil {
1523 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301524 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001525 }
1526 oltSerialNumber := parentDevice.SerialNumber
1527
1528 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1529 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1530 eventContext["serial-number"] = dh.device.SerialNumber
1531 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301532 eventContext["device_id"] = aDeviceID
1533 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001534 logger.Debugw("prepare ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301535 log.Fields{"DeviceId": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001536
1537 /* Populating device event body */
1538 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301539 de.ResourceId = aDeviceID
1540 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001541 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1542 de.Description = fmt.Sprintf("%s Event - %s - %s",
1543 cEventObjectType, cOnuActivatedEvent, "Raised")
1544 } else {
1545 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1546 de.Description = fmt.Sprintf("%s Event - %s - %s",
1547 cEventObjectType, cOnuActivatedEvent, "Cleared")
1548 }
1549 /* Send event to KAFKA */
1550 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1551 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301552 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001553 }
1554 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301555 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001556}
1557
Himani Chawla4d908332020-08-31 12:30:20 +05301558// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301559func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001560 chLSFsm := make(chan Message, 2048)
1561 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301562 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001563 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001564 sFsmName = "LockStateFSM"
1565 } else {
divyadesai4d299552020-08-18 07:13:49 +00001566 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001567 sFsmName = "UnLockStateFSM"
1568 }
mpagenko3af1f032020-06-10 08:53:41 +00001569
Himani Chawla6d2ae152020-09-02 13:11:20 +05301570 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001571 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001572 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001573 return
1574 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301575 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001576 sFsmName, dh.deviceID, chLSFsm)
1577 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301578 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001579 dh.pLockStateFsm = pLSFsm
1580 } else {
1581 dh.pUnlockStateFsm = pLSFsm
1582 }
1583 dh.runUniLockFsm(aAdminState)
1584 } else {
divyadesai4d299552020-08-18 07:13:49 +00001585 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001586 }
1587}
1588
1589// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301590func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001591 /* Uni Port lock/unlock procedure -
1592 ***** should run via 'adminDone' state and generate the argument requested event *****
1593 */
1594 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301595 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001596 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1597 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1598 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001599 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301600 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001601 }
1602 } else {
1603 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1604 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1605 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001606 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301607 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001608 }
1609 }
1610 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001611 if pLSStatemachine.Is(uniStDisabled) {
1612 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001613 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1614 // maybe try a FSM reset and then again ... - TODO!!!
1615 } else {
1616 /***** LockStateFSM started */
1617 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001618 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001619 }
1620 } else {
1621 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001622 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001623 // maybe try a FSM reset and then again ... - TODO!!!
1624 }
1625 } else {
divyadesai4d299552020-08-18 07:13:49 +00001626 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001627 // maybe try a FSM reset and then again ... - TODO!!!
1628 }
1629}
1630
Himani Chawla6d2ae152020-09-02 13:11:20 +05301631//setBackend provides a DB backend for the specified path on the existing KV client
1632func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001633 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1634 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001635 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001636 kvbackend := &db.Backend{
1637 Client: dh.pOpenOnuAc.kvClient,
1638 StoreType: dh.pOpenOnuAc.KVStoreType,
1639 /* address config update acc. to [VOL-2736] */
1640 Address: addr,
1641 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1642 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001643
mpagenkoaf801632020-07-03 10:00:42 +00001644 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001645}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301646func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301647 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001648
mpagenkodff5dda2020-08-28 11:52:01 +00001649 for _, field := range flow.GetOfbFields(apFlowItem) {
1650 switch field.Type {
1651 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1652 {
1653 logger.Debugw("FlowAdd type EthType", log.Fields{"device-id": dh.deviceID,
1654 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1655 }
1656 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1657 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301658 *loIPProto = field.GetIpProto()
mpagenkodff5dda2020-08-28 11:52:01 +00001659 logger.Debugw("FlowAdd type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301660 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1661 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001662 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1663 // avoids installing invalid EVTOCD rule
1664 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1665 log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301666 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1667 return
mpagenkodff5dda2020-08-28 11:52:01 +00001668 }
1669 }
1670 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1671 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301672 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001673 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301674 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001675 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001677 }
1678 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301679 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001680 }
1681 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1682 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301683 *loAddPcp = uint8(field.GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001684 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1685 "PCP": loAddPcp})
1686 }
1687 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1688 {
1689 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1690 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1691 }
1692 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1693 {
1694 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1695 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1696 }
1697 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1698 {
1699 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1700 "IPv4-DST": field.GetIpv4Dst()})
1701 }
1702 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1703 {
1704 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1705 "IPv4-SRC": field.GetIpv4Src()})
1706 }
1707 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1708 {
1709 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1710 "Metadata": field.GetTableMetadata()})
1711 }
1712 /*
1713 default:
1714 {
1715 //all other entires ignored
1716 }
1717 */
1718 }
1719 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301720}
mpagenkodff5dda2020-08-28 11:52:01 +00001721
Himani Chawla6d2ae152020-09-02 13:11:20 +05301722func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001723 for _, action := range flow.GetActions(apFlowItem) {
1724 switch action.Type {
1725 /* not used:
1726 case of.OfpActionType_OFPAT_OUTPUT:
1727 {
1728 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1729 "Output": action.GetOutput()})
1730 }
1731 */
1732 case of.OfpActionType_OFPAT_PUSH_VLAN:
1733 {
1734 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1735 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1736 }
1737 case of.OfpActionType_OFPAT_SET_FIELD:
1738 {
1739 pActionSetField := action.GetSetField()
1740 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
1741 logger.Warnw("FlowAdd action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
1742 "OxcmClass": pActionSetField.Field.OxmClass})
1743 }
1744 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05301745 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001746 logger.Debugw("FlowAdd Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301747 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001748 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05301749 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001750 logger.Debugw("FlowAdd Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301751 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00001752 } else {
1753 logger.Warnw("FlowAdd action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
1754 "Type": pActionSetField.Field.GetOfbField().Type})
1755 }
1756 }
1757 /*
1758 default:
1759 {
1760 //all other entires ignored
1761 }
1762 */
1763 }
1764 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05301765}
1766
1767//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05301768func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05301769 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
1770 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
1771 var loAddPcp, loSetPcp uint8
1772 var loIPProto uint32
1773 /* the TechProfileId is part of the flow Metadata - compare also comment within
1774 * OLT-Adapter:openolt_flowmgr.go
1775 * Metadata 8 bytes:
1776 * Most Significant 2 Bytes = Inner VLAN
1777 * Next 2 Bytes = Tech Profile ID(TPID)
1778 * Least Significant 4 Bytes = Port ID
1779 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
1780 * subscriber related flows.
1781 */
1782
1783 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
1784 if metadata == 0 {
1785 logger.Debugw("FlowAdd invalid metadata - abort",
1786 log.Fields{"device-id": dh.deviceID})
1787 return errors.New("flowAdd invalid metadata")
1788 }
1789 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
1790 logger.Debugw("FlowAdd TechProfileId", log.Fields{"device-id": dh.deviceID, "TP-Id": loTpID})
1791
1792 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
1793 if loIPProto == 2 {
1794 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1795 // avoids installing invalid EVTOCD rule
1796 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1797 log.Fields{"device-id": dh.deviceID,
1798 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
1799 return nil
1800 }
1801 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00001802
1803 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1804 logger.Errorw("FlowAdd aborted - SetVlanId undefined, but MatchVid set", log.Fields{
1805 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
1806 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
1807 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
1808 //TODO!!: Use DeviceId within the error response to rwCore
1809 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Himani Chawla26e555c2020-08-31 12:30:20 +05301810 return errors.New("flowAdd Set/Match VlanId inconsistent")
mpagenkodff5dda2020-08-28 11:52:01 +00001811 }
1812 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
1813 logger.Debugw("FlowAdd vlan-any/copy", log.Fields{"device-id": dh.deviceID})
1814 loSetVlan = loMatchVlan //both 'transparent' (copy any)
1815 } else {
1816 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
1817 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1818 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05301819 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001820 }
1821 logger.Debugw("FlowAdd vlan-set", log.Fields{"device-id": dh.deviceID})
1822 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301823 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001824 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00001825 }
1826 return dh.createVlanFilterFsm(apUniPort,
1827 loTpID, loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
1828}
1829
Himani Chawla26e555c2020-08-31 12:30:20 +05301830// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
Himani Chawla6d2ae152020-09-02 13:11:20 +05301831func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort,
mpagenkodff5dda2020-08-28 11:52:01 +00001832 aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
1833 chVlanFilterFsm := make(chan Message, 2048)
1834
Himani Chawla6d2ae152020-09-02 13:11:20 +05301835 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00001836 if pDevEntry == nil {
1837 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301838 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001839 }
1840
1841 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
1842 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", dh.deviceID, chVlanFilterFsm,
1843 dh.pOpenOnuAc.AcceptIncrementalEvto, aMatchVlan, aSetVlan, aSetPcp)
1844 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05301845 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001846 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1847 if pVlanFilterStatemachine != nil {
1848 if pVlanFilterStatemachine.Is(vlanStDisabled) {
1849 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
1850 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301851 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001852 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301853 /***** UniVlanConfigFsm started */
1854 logger.Debugw("UniVlanConfigFsm started", log.Fields{
1855 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
1856 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00001857 } else {
1858 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
1859 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301860 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001861 }
1862 } else {
1863 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
1864 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301865 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001866 }
1867 } else {
1868 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
1869 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05301870 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001871 }
1872 return nil
1873}
1874
1875//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301876func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00001877 //TODO!! verify and start pending flow configuration
1878 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
1879 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05301880 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00001881 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
1882 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1883 if pVlanFilterStatemachine != nil {
1884 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
1885 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
1886 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
1887 } else {
1888 /***** UniVlanConfigFsm continued */
1889 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
1890 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
1891 "UniPort": apUniPort.portNo})
1892 }
1893 } else {
1894 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
1895 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
1896 }
1897 } else {
1898 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
1899 "device-id": dh.deviceID})
1900 }
1901
1902 } // else: nothing to do
1903}
1904
1905//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
1906// 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 +05301907func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00001908 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
1909 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
1910 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05301911 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00001912}