blob: 9e9845265aeaa63715cbd68c973de7ddc6255ef8 [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})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000240 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530241}
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()})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000264 return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530265 }
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 {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000271
272 pDevEntry := dh.getOnuDeviceEntry(true)
273 if pDevEntry == nil {
274 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
275 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
276 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530277 if dh.pOnuTP == nil {
278 //should normally not happen ...
279 logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
280 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000281 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530282 }
283 if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock") {
284 // I've seen cases for this request, where the device was already stopped
285 logger.Warnw("TechProf stopped: device-unreachable", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000286 return fmt.Errorf("device-unreachable: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530287 }
288
289 msgBody := msg.GetBody()
290 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
291 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
292 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
293 "device-id": dh.deviceID, "error": err})
294 return err
295 }
296
297 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000298 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
299 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530300 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000301 defer dh.pOnuTP.unlockTpProcMutex()
302 pDevEntry.lockOnuKVStoreMutex()
303 defer pDevEntry.unlockOnuKVStoreMutex()
304
305 if techProfMsg.UniId > 255 {
306 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
307 techProfMsg.UniId, dh.deviceID))
308 }
309 uniID := uint8(techProfMsg.UniId)
310
311 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530312 // if there has been some change for some uni TechProfilePath
313 //in order to allow concurrent calls to other dh instances we do not wait for execution here
314 //but doing so we can not indicate problems to the caller (who does what with that then?)
315 //by now we just assume straightforward successful execution
316 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
317 // possible problems to the caller later autonomously
318
319 // deadline context to ensure completion of background routines waited for
320 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
321 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
322 dctx, cancel := context.WithDeadline(context.Background(), deadline)
323
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000324 dh.pOnuTP.resetTpProcessingErrorIndication()
325 pDevEntry.resetKvProcessingErrorIndication()
326
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 var wg sync.WaitGroup
328 wg.Add(2) // for the 2 go routines to finish
329 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000330 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
331 go pDevEntry.updateOnuKvStore(dctx, &wg)
332 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
333
334 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530335 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000336 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530337 return nil
338}
339
Himani Chawla6d2ae152020-09-02 13:11:20 +0530340func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530341 msg *ic.InterAdapterMessage) error {
342
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000343 pDevEntry := dh.getOnuDeviceEntry(true)
344 if pDevEntry == nil {
345 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
346 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
347 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 if dh.pOnuTP == nil {
349 //should normally not happen ...
350 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
351 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000352 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 }
354
355 msgBody := msg.GetBody()
356 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
357 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
358 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
359 "device-id": dh.deviceID, "error": err})
360 return err
361 }
362
363 //compare TECH_PROFILE_DOWNLOAD_REQUEST
364 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 defer dh.pOnuTP.unlockTpProcMutex()
366 pDevEntry.lockOnuKVStoreMutex()
367 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530368
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000369 if delGemPortMsg.UniId > 255 {
370 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
371 delGemPortMsg.UniId, dh.deviceID))
372 }
373 uniID := uint8(delGemPortMsg.UniId)
Himani Chawla26e555c2020-08-31 12:30:20 +0530374
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
376 // deadline context to ensure completion of background routines waited for
377 deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
378 dctx, cancel := context.WithDeadline(context.Background(), deadline)
379
380 dh.pOnuTP.resetTpProcessingErrorIndication()
381 pDevEntry.resetKvProcessingErrorIndication()
382
383 var wg sync.WaitGroup
384 wg.Add(2) // for the 2 go routines to finish
385 go pDevEntry.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
386 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
387 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
388 go pDevEntry.updateOnuKvStore(dctx, &wg)
389 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
390
391 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
392 }
393 return nil
Himani Chawla26e555c2020-08-31 12:30:20 +0530394}
395
Himani Chawla6d2ae152020-09-02 13:11:20 +0530396func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530397 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000398
399 pDevEntry := dh.getOnuDeviceEntry(true)
400 if pDevEntry == nil {
401 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
402 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
403 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 if dh.pOnuTP == nil {
405 //should normally not happen ...
406 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
407 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530409 }
410
411 msgBody := msg.GetBody()
412 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
413 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
414 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
415 "device-id": dh.deviceID, "error": err})
416 return err
417 }
418
419 //compare TECH_PROFILE_DOWNLOAD_REQUEST
420 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000421 defer dh.pOnuTP.unlockTpProcMutex()
422 pDevEntry.lockOnuKVStoreMutex()
423 defer pDevEntry.unlockOnuKVStoreMutex()
424
425 if delTcontMsg.UniId > 255 {
426 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
427 delTcontMsg.UniId, dh.deviceID))
428 }
429 uniID := uint8(delTcontMsg.UniId)
430
431 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530432 // deadline context to ensure completion of background routines waited for
433 deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
434 dctx, cancel := context.WithDeadline(context.Background(), deadline)
435
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 dh.pOnuTP.resetTpProcessingErrorIndication()
437 pDevEntry.resetKvProcessingErrorIndication()
438
Himani Chawla26e555c2020-08-31 12:30:20 +0530439 var wg sync.WaitGroup
440 wg.Add(2) // for the 2 go routines to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441 go pDevEntry.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530442 cResourceTcont, delTcontMsg.AllocId, &wg)
443 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000444 go pDevEntry.updateOnuKvStore(dctx, &wg)
445 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
446
447 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530448 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 return nil
450}
451
Himani Chawla6d2ae152020-09-02 13:11:20 +0530452//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000453// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
454// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530455func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000456 msgID := msg.Header.Id
457 msgType := msg.Header.Type
458 fromTopic := msg.Header.FromTopic
459 toTopic := msg.Header.ToTopic
460 toDeviceID := msg.Header.ToDeviceId
461 proxyDeviceID := msg.Header.ProxyDeviceId
462 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
463 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
464
465 switch msgType {
466 case ic.InterAdapterMessageType_OMCI_REQUEST:
467 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530468 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000469 }
470 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
471 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000473 }
mpagenkoaf801632020-07-03 10:00:42 +0000474 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
475 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530476 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000477 }
478 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
479 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000481
mpagenkoaf801632020-07-03 10:00:42 +0000482 }
483 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
484 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000486 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000487 default:
488 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000489 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490 "msgType": msg.Header.Type, "device-id": dh.deviceID})
491 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000492 }
493 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000494}
495
mpagenkodff5dda2020-08-28 11:52:01 +0000496//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530497func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000498 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
499
500 //Remove flows
501 if apOfFlowChanges.ToRemove != nil {
502 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
503 logger.Debugw("incremental flow item remove", log.Fields{"deviceId": dh.deviceID,
504 "Item": flowItem})
505 }
506 }
507 if apOfFlowChanges.ToAdd != nil {
508 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
509 if flowItem.GetCookie() == 0 {
510 logger.Debugw("incremental flow add - no cookie - ignore", log.Fields{
511 "deviceId": dh.deviceID})
512 continue
513 }
514 flowInPort := flow.GetInPort(flowItem)
515 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
516 logger.Errorw("flow inPort invalid", log.Fields{"deviceID": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000517 return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000518 } else if flowInPort == dh.ponPortNumber {
519 //this is some downstream flow
520 logger.Debugw("incremental flow ignore downstream", log.Fields{
521 "deviceId": dh.deviceID, "inPort": flowInPort})
522 continue
523 } else {
524 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530525 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000526 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
527 loUniPort = uniPort
528 } else {
529 logger.Errorw("flow inPort not found in UniPorts",
530 log.Fields{"deviceID": dh.deviceID, "inPort": flowInPort})
531 return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
532 }
533 flowOutPort := flow.GetOutPort(flowItem)
534 logger.Debugw("incremental flow-add port indications", log.Fields{
535 "deviceId": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
536 "uniPortName": loUniPort.name})
537 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
538 //abort processing in error case
539 if err != nil {
540 return err
541 }
542 }
543 }
544 }
545 return nil
546}
547
Himani Chawla6d2ae152020-09-02 13:11:20 +0530548//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenko3af1f032020-06-10 08:53:41 +0000549// TODO!!! Clarify usage of this method, it is for sure not used within ONOS (OLT) device disable
550// maybe it is obsolete by now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530551func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000552 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000553
mpagenko3af1f032020-06-10 08:53:41 +0000554 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly - inblock
555 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
556 if dh.deviceReason != "omci-admin-lock" {
557 // disable UNI ports/ONU
558 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
559 // here the result of the processing is not checked (trusted in background) *****
560 if dh.pLockStateFsm == nil {
561 dh.createUniLockFsm(true, UniAdminStateDone)
562 } else { //LockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +0530563 dh.pLockStateFsm.setSuccessEvent(UniAdminStateDone)
mpagenko3af1f032020-06-10 08:53:41 +0000564 dh.runUniLockFsm(true)
565 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300566
mpagenko3af1f032020-06-10 08:53:41 +0000567 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000568 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000569 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +0000570 }
571 dh.deviceReason = "omci-admin-lock"
572 //200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
573 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
574 voltha.OperStatus_UNKNOWN); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000575 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000576 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +0000577 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300578 }
579}
580
Himani Chawla6d2ae152020-09-02 13:11:20 +0530581//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530582func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000583 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000584
585 // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...(like python code)
ozgecanetsiafce57b12020-05-25 14:39:35 +0300586 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
587 voltha.OperStatus_ACTIVE); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000588 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000589 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300590 }
591
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000592 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
593 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000594 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000595 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300596 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000597 dh.deviceReason = "onu-reenabled"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000598
599 // enable ONU/UNI ports
600 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
601 // here the result of the processing is not checked (trusted in background) *****
602 if dh.pUnlockStateFsm == nil {
603 dh.createUniLockFsm(false, UniAdminStateDone)
604 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +0530605 dh.pUnlockStateFsm.setSuccessEvent(UniAdminStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000606 dh.runUniLockFsm(false)
607 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300608}
609
Himani Chawla6d2ae152020-09-02 13:11:20 +0530610func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000611 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
612
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000613 pDevEntry := dh.getOnuDeviceEntry(true)
614 if pDevEntry == nil {
615 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
616 return
617 }
618 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000619 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
620 dh.reconciling = false
621 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000622 }
Himani Chawla4d908332020-08-31 12:30:20 +0530623 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000624 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
625 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
626 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
627 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530628 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000629}
630
Himani Chawla6d2ae152020-09-02 13:11:20 +0530631func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000632 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
633
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000634 pDevEntry := dh.getOnuDeviceEntry(true)
635 if pDevEntry == nil {
636 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
637 return
638 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000639
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000640 dh.pOnuTP.lockTpProcMutex()
641 defer dh.pOnuTP.unlockTpProcMutex()
642
643 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000644 // deadline context to ensure completion of background routines waited for
645 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
646 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
647 dctx, cancel := context.WithDeadline(context.Background(), deadline)
648
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000649 dh.pOnuTP.resetTpProcessingErrorIndication()
650
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000651 var wg sync.WaitGroup
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000652 wg.Add(1) // for the 1 go routine to finish
653 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPath, &wg)
654 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
655
656 if err := dh.pOnuTP.getTpProcessingErrorIndication(); err != nil {
657 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
658 }
659 }
660}
661
662func (dh *deviceHandler) reconcileDeviceFlowConfig() {
663 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
664
665 pDevEntry := dh.getOnuDeviceEntry(true)
666 if pDevEntry == nil {
667 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000668 return
669 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000670 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
671 var uniPort *onuUniPort
672 var exist bool
673 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
674 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
675 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "deviceID": dh.deviceID})
676 return
677 }
678 for _, flowData := range uniData.PersFlowParams {
679 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
680 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.TpID, uint16(flowData.MatchVid),
681 uint16(flowData.SetVid), uint8(flowData.SetPcp)); err != nil {
682 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
683 }
684
685 } else {
686 if err := dh.createVlanFilterFsm(uniPort, flowData.TpID, uint16(flowData.MatchVid), uint16(flowData.SetVid),
687 uint8(flowData.SetPcp), OmciVlanFilterDone); err != nil {
688 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
689 }
690 }
691 }
692 }
693}
694
695func (dh *deviceHandler) reconcileMetrics() {
696 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
697
698 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000699 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000700}
701
Himani Chawla6d2ae152020-09-02 13:11:20 +0530702func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000703 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000704
705 pDevEntry := dh.getOnuDeviceEntry(true)
706 if pDevEntry == nil {
707 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
708 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000709 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000710 pDevEntry.lockOnuKVStoreMutex()
711 defer pDevEntry.unlockOnuKVStoreMutex()
712
713 // deadline context to ensure completion of background routines waited for
714 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
715 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
716 dctx, cancel := context.WithDeadline(context.Background(), deadline)
717
718 pDevEntry.resetKvProcessingErrorIndication()
719
720 var wg sync.WaitGroup
721 wg.Add(1) // for the 1 go routine to finish
722 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
723 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
724
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000725 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000726 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000727}
728
Himani Chawla6d2ae152020-09-02 13:11:20 +0530729func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000730 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300731 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000732 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000733 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300734 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530735 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530736 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
737 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
738 return err
739 }
ozgecanetsiae11479f2020-07-06 09:44:47 +0300740 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
741 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000742 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000743 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300744 return err
745 }
746 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting-onu"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000747 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000748 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300749 return err
750 }
751 dh.deviceReason = "rebooting-onu"
752 return nil
753}
754
Himani Chawla6d2ae152020-09-02 13:11:20 +0530755// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000756// #####################################################################################
757
758// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530759// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000760
Himani Chawla6d2ae152020-09-02 13:11:20 +0530761func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000762 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})
763}
764
765// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530766func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000767
768 logger.Debug("doStateInit-started")
769 var err error
770
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000771 // populate what we know. rest comes later after mib sync
772 dh.device.Root = false
773 dh.device.Vendor = "OpenONU"
774 dh.device.Model = "go"
775 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000776 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000777
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000778 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000779
780 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530781 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000782 } else {
783 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
784 log.Fields{"device-id": dh.deviceID})
785 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000786
Himani Chawla4d908332020-08-31 12:30:20 +0530787 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000788 dh.ponPortNumber = dh.device.ParentPortNo
789
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000790 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
791 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
792 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000793 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000794 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530795 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000796
797 /*
798 self._pon = PonPort.create(self, self._pon_port_number)
799 self._pon.add_peer(self.parent_id, self._pon_port_number)
800 self.logger.debug('adding-pon-port-to-agent',
801 type=self._pon.get_port().type,
802 admin_state=self._pon.get_port().admin_state,
803 oper_status=self._pon.get_port().oper_status,
804 )
805 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000806 if !dh.reconciling {
807 logger.Debugw("adding-pon-port", log.Fields{"deviceID": dh.deviceID, "ponPortNo": dh.ponPortNumber})
808 var ponPortNo uint32 = 1
809 if dh.ponPortNumber != 0 {
810 ponPortNo = dh.ponPortNumber
811 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000812
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000813 pPonPort := &voltha.Port{
814 PortNo: ponPortNo,
815 Label: fmt.Sprintf("pon-%d", ponPortNo),
816 Type: voltha.Port_PON_ONU,
817 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530818 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000819 PortNo: ponPortNo}}, // Peer port is parent's port number
820 }
821 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
822 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
823 e.Cancel(err)
824 return
825 }
826 } else {
827 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000828 }
829 logger.Debug("doStateInit-done")
830}
831
832// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530833func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000834
835 logger.Debug("postInit-started")
836 var err error
837 /*
838 dh.Client = oop.NewOpenoltClient(dh.clientCon)
839 dh.pTransitionMap.Handle(ctx, GrpcConnected)
840 return nil
841 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530842 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
843 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000844 e.Cancel(err)
845 return
846 }
847
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000848 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530849 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000850 // reconcilement will be continued after mib download is done
851 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000852 /*
853 ############################################################################
854 # Setup Alarm handler
855 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
856 device.serial_number)
857 ############################################################################
858 # Setup PM configuration for this device
859 # Pass in ONU specific options
860 kwargs = {
861 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
862 'heartbeat': self.heartbeat,
863 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
864 }
865 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
866 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
867 self.logical_device_id, device.serial_number,
868 grouped=True, freq_override=False, **kwargs)
869 pm_config = self._pm_metrics.make_proto()
870 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
871 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
872 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
873
874 # Note, ONU ID and UNI intf set in add_uni_port method
875 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
876 ani_ports=[self._pon])
877
878 # Code to Run OMCI Test Action
879 kwargs_omci_test_action = {
880 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
881 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
882 }
883 serial_number = device.serial_number
884 self._test_request = OmciTestRequest(self.core_proxy,
885 self.omci_agent, self.device_id,
886 AniG, serial_number,
887 self.logical_device_id,
888 exclusive=False,
889 **kwargs_omci_test_action)
890
891 self.enabled = True
892 else:
893 self.logger.info('onu-already-activated')
894 */
895 logger.Debug("postInit-done")
896}
897
898// doStateConnected get the device info and update to voltha core
899// for comparison of the original method (not that easy to uncomment): compare here:
900// voltha-openolt-adapter/adaptercore/device_handler.go
901// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530902func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000903
904 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530905 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000906 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000907 logger.Debug("doStateConnected-done")
908}
909
910// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530911func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000912
913 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530914 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000915 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000916 logger.Debug("doStateUp-done")
917
918 /*
919 // Synchronous call to update device state - this method is run in its own go routine
920 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
921 voltha.OperStatus_ACTIVE); err != nil {
922 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
923 return err
924 }
925 return nil
926 */
927}
928
929// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +0530930func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000931
932 logger.Debug("doStateDown-started")
933 var err error
934
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000935 device := dh.device
936 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000937 /*TODO: needs to handle error scenarios */
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000938 logger.Error("Failed to fetch handler device")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000939 e.Cancel(err)
940 return
941 }
942
943 cloned := proto.Clone(device).(*voltha.Device)
944 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
945 /*
946 // Update the all ports state on that device to disable
947 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
948 logger.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
949 return er
950 }
951
952 //Update the device oper state and connection status
953 cloned.OperStatus = voltha.OperStatus_UNKNOWN
954 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
955 dh.device = cloned
956
957 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
958 logger.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
959 return er
960 }
961
962 //get the child device for the parent device
963 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
964 if err != nil {
965 logger.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
966 return err
967 }
968 for _, onuDevice := range onuDevices.Items {
969
970 // Update onu state as down in onu adapter
971 onuInd := oop.OnuIndication{}
972 onuInd.OperState = "down"
973 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
974 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
975 if er != nil {
976 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
977 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
978 //Do not return here and continue to process other ONUs
979 }
980 }
981 // * Discovered ONUs entries need to be cleared , since after OLT
982 // is up, it starts sending discovery indications again* /
983 dh.discOnus = sync.Map{}
984 logger.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
985 return nil
986 */
Himani Chawla4d908332020-08-31 12:30:20 +0530987 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000988 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000989 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000990}
991
Himani Chawla6d2ae152020-09-02 13:11:20 +0530992// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000993// #################################################################################
994
995// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530996// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +0530999func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001000 dh.lockDevice.RLock()
1001 pOnuDeviceEntry := dh.pOnuOmciDevice
1002 if aWait && pOnuDeviceEntry == nil {
1003 //keep the read sema short to allow for subsequent write
1004 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001005 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001006 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1007 // so it might be needed to wait here for that event with some timeout
1008 select {
1009 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001010 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001011 return nil
1012 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001013 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001014 // if written now, we can return the written value without sema
1015 return dh.pOnuOmciDevice
1016 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001017 }
mpagenko3af1f032020-06-10 08:53:41 +00001018 dh.lockDevice.RUnlock()
1019 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001020}
1021
Himani Chawla6d2ae152020-09-02 13:11:20 +05301022//setOnuDeviceEntry sets the ONU device entry within the handler
1023func (dh *deviceHandler) setOnuDeviceEntry(
1024 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001025 dh.lockDevice.Lock()
1026 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001027 dh.pOnuOmciDevice = apDeviceEntry
1028 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001029}
1030
Himani Chawla6d2ae152020-09-02 13:11:20 +05301031//addOnuDeviceEntry creates a new ONU device or returns the existing
1032func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001033 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001034
Himani Chawla6d2ae152020-09-02 13:11:20 +05301035 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001036 if deviceEntry == nil {
1037 /* costum_me_map in python code seems always to be None,
1038 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1039 /* also no 'clock' argument - usage open ...*/
1040 /* and no alarm_db yet (oo.alarm_db) */
Himani Chawla6d2ae152020-09-02 13:11:20 +05301041 deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
mpagenkoaf801632020-07-03 10:00:42 +00001042 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001043 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001044 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
Himani Chawla6d2ae152020-09-02 13:11:20 +05301045 onuTechProfProc := newOnuUniTechProf(ctx, dh.deviceID, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001046 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301047 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001048 // fire deviceEntry ready event to spread to possibly waiting processing
1049 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001050 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001051 } else {
divyadesai4d299552020-08-18 07:13:49 +00001052 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001053 }
1054 // might be updated with some error handling !!!
1055 return nil
1056}
1057
1058// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301059func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001060 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1061 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1062
1063 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001064
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001065 if !dh.reconciling {
1066 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1067 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1068 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1069 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1070 }
1071 } else {
1072 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1073 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001075 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1076 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1077 // 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 +00001078 // 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 +00001079 // so let's just try to keep it simple ...
1080 /*
1081 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1082 if err != nil || device == nil {
1083 //TODO: needs to handle error scenarios
1084 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1085 return errors.New("Voltha Device not found")
1086 }
1087 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001088
Himani Chawla6d2ae152020-09-02 13:11:20 +05301089 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001090 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301091 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301092 return err
1093 }
mpagenko3af1f032020-06-10 08:53:41 +00001094 } else {
divyadesai4d299552020-08-18 07:13:49 +00001095 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001096 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001097 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001098 if !dh.reconciling {
1099 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1100 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1101 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1102 }
1103 } else {
1104 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1105 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001106 }
mpagenko3af1f032020-06-10 08:53:41 +00001107 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108
1109 /* this might be a good time for Omci Verify message? */
1110 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301111 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001112 dh.device.Id, pDevEntry.PDevOmciCC,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001113 true, true) //eclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301114 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115
1116 /* give the handler some time here to wait for the OMCi verification result
1117 after Timeout start and try MibUpload FSM anyway
1118 (to prevent stopping on just not supported OMCI verification from ONU) */
1119 select {
1120 case <-time.After(2 * time.Second):
1121 logger.Warn("omci start-verification timed out (continue normal)")
1122 case testresult := <-verifyExec:
1123 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1124 }
1125
1126 /* In py code it looks earlier (on activate ..)
1127 # Code to Run OMCI Test Action
1128 kwargs_omci_test_action = {
1129 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1130 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1131 }
1132 serial_number = device.serial_number
1133 self._test_request = OmciTestRequest(self.core_proxy,
1134 self.omci_agent, self.device_id,
1135 AniG, serial_number,
1136 self.logical_device_id,
1137 exclusive=False,
1138 **kwargs_omci_test_action)
1139 ...
1140 # Start test requests after a brief pause
1141 if not self._test_request_started:
1142 self._test_request_started = True
1143 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1144 reactor.callLater(tststart, self._test_request.start_collector)
1145
1146 */
1147 /* which is then: in omci_test_request.py : */
1148 /*
1149 def start_collector(self, callback=None):
1150 """
1151 Start the collection loop for an adapter if the frequency > 0
1152
1153 :param callback: (callable) Function to call to collect PM data
1154 """
1155 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1156 if callback is None:
1157 callback = self.perform_test_omci
1158
1159 if self.lc is None:
1160 self.lc = LoopingCall(callback)
1161
1162 if self.default_freq > 0:
1163 self.lc.start(interval=self.default_freq / 10)
1164
1165 def perform_test_omci(self):
1166 """
1167 Perform the initial test request
1168 """
1169 ani_g_entities = self._device.configuration.ani_g_entities
1170 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1171 is not None else None
1172 self._entity_id = ani_g_entities_ids[0]
1173 self.logger.info('perform-test', entity_class=self._entity_class,
1174 entity_id=self._entity_id)
1175 try:
1176 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1177 result = yield self._device.omci_cc.send(frame)
1178 if not result.fields['omci_message'].fields['success_code']:
1179 self.logger.info('Self-Test Submitted Successfully',
1180 code=result.fields[
1181 'omci_message'].fields['success_code'])
1182 else:
1183 raise TestFailure('Test Failure: {}'.format(
1184 result.fields['omci_message'].fields['success_code']))
1185 except TimeoutError as e:
1186 self.deferred.errback(failure.Failure(e))
1187
1188 except Exception as e:
1189 self.logger.exception('perform-test-Error', e=e,
1190 class_id=self._entity_class,
1191 entity_id=self._entity_id)
1192 self.deferred.errback(failure.Failure(e))
1193
1194 */
1195
1196 // PM related heartbeat??? !!!TODO....
1197 //self._heartbeat.enabled = True
1198
mpagenko1cc3cb42020-07-27 15:24:38 +00001199 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1200 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1201 * 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 +05301202 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001203 */
1204 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001205 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001206 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001207 if pMibUlFsm.Is(ulStDisabled) {
1208 if err := pMibUlFsm.Event(ulEvStart); err != nil {
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001209 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001210 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301211 }
1212 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1213 //Determine ONU status and start/re-start MIB Synchronization tasks
1214 //Determine if this ONU has ever synchronized
1215 if true { //TODO: insert valid check
1216 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
1217 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001218 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001219 }
Himani Chawla4d908332020-08-31 12:30:20 +05301220 } else {
1221 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
1222 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001223 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301224 }
1225 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1226 //Examine the MIB Data Sync
1227 // callbacks to be handled:
1228 // Event(ulEvSuccess)
1229 // Event(ulEvTimeout)
1230 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001231 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001232 } else {
1233 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current())})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001234 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001235 }
1236 } else {
divyadesai4d299552020-08-18 07:13:49 +00001237 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001238 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001239 }
1240 return nil
1241}
1242
Himani Chawla6d2ae152020-09-02 13:11:20 +05301243func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001244 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1245 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001246 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001247 //stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
Himani Chawla6d2ae152020-09-02 13:11:20 +05301248 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001249 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001250 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001251 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001252 }
1253
1254 switch dh.deviceReason {
1255 case "starting-openomci":
1256 { //MIBSync FSM may run
1257 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1258 if pMibUlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301259 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
mpagenko3af1f032020-06-10 08:53:41 +00001260 }
1261 }
1262 case "discovery-mibsync-complete":
1263 { //MibDownload may run
1264 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1265 if pMibDlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301266 _ = pMibDlFsm.Event(dlEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001267 }
1268 }
1269 default:
mpagenko3dbcdd22020-07-22 07:38:45 +00001270 {
1271 //port lock/unlock FSM's may be active
mpagenko3af1f032020-06-10 08:53:41 +00001272 if dh.pUnlockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301273 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001274 }
1275 if dh.pLockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301276 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001277 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001278 //techProfile related PonAniConfigFsm FSM may be active
1279 // maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1280 if dh.pOnuTP.pAniConfigFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301281 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +00001282 }
mpagenkodff5dda2020-08-28 11:52:01 +00001283 for _, uniPort := range dh.uniEntityMap {
1284 //reset the TechProfileConfig Done state for all (active) UNI's
Himani Chawla26e555c2020-08-31 12:30:20 +05301285 dh.pOnuTP.setConfigDone(uniPort.uniID, false)
1286 // reset the possibly existing VlanConfigFsm
1287 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00001288 //VlanFilterFsm exists and was already started
1289 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1290 if pVlanFilterStatemachine != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301291 _ = pVlanFilterStatemachine.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +00001292 }
1293 }
1294 }
mpagenko3af1f032020-06-10 08:53:41 +00001295 }
1296 //TODO!!! care about PM/Alarm processing once started
1297 }
1298 //TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
Himani Chawla4d908332020-08-31 12:30:20 +05301299 // (mainly the still separate 'Event states')
mpagenko3af1f032020-06-10 08:53:41 +00001300 // so it is questionable, how this is resolved after some possible re-enable
1301 // assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
1302
1303 //stop/remove(?) the device entry
Himani Chawla6d2ae152020-09-02 13:11:20 +05301304 _ = pDevEntry.stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
mpagenko3af1f032020-06-10 08:53:41 +00001305
1306 //TODO!!! remove existing traffic profiles
1307 /* from py code, if TP's exist, remove them - not yet implemented
1308 self._tp = dict()
1309 # Let TP download happen again
1310 for uni_id in self._tp_service_specific_task:
1311 self._tp_service_specific_task[uni_id].clear()
1312 for uni_id in self._tech_profile_download_done:
1313 self._tech_profile_download_done[uni_id].clear()
1314 */
1315
1316 dh.disableUniPortStateUpdate()
1317
1318 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001319 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001320 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001321 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001322 // abort: system behavior is just unstable ...
1323 return err
1324 }
1325 dh.deviceReason = "stopping-openomci"
1326
1327 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1328 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001329 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001330 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001331 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001332 // abort: system behavior is just unstable ...
1333 return err
1334 }
1335 } else {
divyadesai4d299552020-08-18 07:13:49 +00001336 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001337 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001338 return nil
1339}
1340
Himani Chawla6d2ae152020-09-02 13:11:20 +05301341func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301342 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1343 if !dh.reconciling {
1344 //initiate DevStateUpdate
1345 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1346 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1347 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
1348 "device-id": dh.deviceID, "error": err})
1349 } else {
1350 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
1351 }
1352 } else {
1353 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1354 log.Fields{"device-id": dh.deviceID})
1355 }
1356 //set internal state anyway - as it was done
1357 dh.deviceReason = "discovery-mibsync-complete"
1358
1359 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301360 pDevEntry := dh.getOnuDeviceEntry(false)
1361 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301362 for _, mgmtEntityID := range unigInstKeys {
1363 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1364 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301365 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301366 i++
1367 }
1368 } else {
1369 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1370 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301371 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301372 for _, mgmtEntityID := range veipInstKeys {
1373 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1374 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301375 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301376 i++
1377 }
1378 } else {
1379 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1380 }
1381 if i == 0 {
1382 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1383 }
1384
1385 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1386 * left the code here as comment in case such processing should prove needed unexpectedly
1387 // Init Uni Ports to Admin locked state
1388 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1389 // *** should generate UniLockStateDone event *****
1390 if dh.pLockStateFsm == nil {
1391 dh.createUniLockFsm(true, UniLockStateDone)
1392 } else { //LockStateFSM already init
1393 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1394 dh.runUniLockFsm(true)
1395 }
1396 }
1397 case UniLockStateDone:
1398 {
1399 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1400 * lockState processing commented out
1401 */
1402 /* Mib download procedure -
1403 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1404 */
1405 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1406 if pMibDlFsm != nil {
1407 if pMibDlFsm.Is(dlStDisabled) {
1408 if err := pMibDlFsm.Event(dlEvStart); err != nil {
1409 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"err": err})
1410 // maybe try a FSM reset and then again ... - TODO!!!
1411 } else {
1412 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1413 // maybe use more specific states here for the specific download steps ...
1414 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
1415 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"err": err})
1416 } else {
1417 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1418 //Begin MIB data download (running autonomously)
1419 }
1420 }
1421 } else {
1422 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current())})
1423 // maybe try a FSM reset and then again ... - TODO!!!
1424 }
1425 /***** Mib download started */
1426 } else {
1427 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1428 }
1429}
1430
Himani Chawla6d2ae152020-09-02 13:11:20 +05301431func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301432 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1433 //initiate DevStateUpdate
1434 if !dh.reconciling {
1435 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1436 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1437 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1438 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1439 } else {
1440 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1441 }
1442 } else {
1443 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1444 log.Fields{"device-id": dh.deviceID})
1445 }
1446 if !dh.reconciling {
1447 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1448 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1449 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
1450 log.Fields{"device-id": dh.deviceID, "error": err})
1451 } else {
1452 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
1453 }
1454 } else {
1455 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1456 log.Fields{"device-id": dh.deviceID})
1457 }
1458 //set internal state anyway - as it was done
1459 dh.deviceReason = "initial-mib-downloaded"
1460 // *** should generate UniUnlockStateDone event *****
1461 if dh.pUnlockStateFsm == nil {
1462 dh.createUniLockFsm(false, UniUnlockStateDone)
1463 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301464 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301465 dh.runUniLockFsm(false)
1466 }
1467}
1468
Himani Chawla6d2ae152020-09-02 13:11:20 +05301469func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301470 go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
1471
1472 if !dh.reconciling {
1473 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1474 raisedTs := time.Now().UnixNano()
1475 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1476 } else {
1477 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1478 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301479 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001480 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301481 }
1482}
1483
Himani Chawla6d2ae152020-09-02 13:11:20 +05301484func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301485 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1486 // attention: the device reason update is done based on ONU-UNI-Port related activity
1487 // - which may cause some inconsistency
1488 if dh.deviceReason != "tech-profile-config-download-success" {
1489 // which may be the case from some previous actvity on another UNI Port of the ONU
1490 if !dh.reconciling {
1491 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1492 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1493 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
1494 log.Fields{"device-id": dh.deviceID, "error": err})
1495 } else {
1496 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
1497 log.Fields{"device-id": dh.deviceID})
1498 }
1499 } else {
1500 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
1501 log.Fields{"device-id": dh.deviceID})
1502 }
1503 //set internal state anyway - as it was done
1504 dh.deviceReason = "tech-profile-config-download-success"
1505 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001506 if dh.reconciling {
1507 go dh.reconcileDeviceFlowConfig()
1508 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301509}
1510
Himani Chawla6d2ae152020-09-02 13:11:20 +05301511func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301512 logger.Debugw("OmciVlanFilterDone event received",
1513 log.Fields{"device-id": dh.deviceID})
1514 // attention: the device reason update is done based on ONU-UNI-Port related activity
1515 // - which may cause some inconsistency
1516 // yield self.core_proxy.device_reason_update(self.device_id, 'omci-flows-pushed')
1517
1518 if dh.deviceReason != "omci-flows-pushed" {
1519 // which may be the case from some previous actvity on another UNI Port of the ONU
1520 // or even some previous flow add activity on the same port
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001521 if !dh.reconciling {
1522 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1523 logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
1524 log.Fields{"device-id": dh.deviceID, "error": err})
1525 } else {
1526 logger.Infow("updated dev reason to ''omci-flows-pushed'",
1527 log.Fields{"device-id": dh.deviceID})
1528 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301529 } else {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001530 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Himani Chawla26e555c2020-08-31 12:30:20 +05301531 log.Fields{"device-id": dh.deviceID})
1532 }
1533 //set internal state anyway - as it was done
1534 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001535
1536 if dh.reconciling {
1537 go dh.reconcileMetrics()
1538 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301539 }
1540}
1541
Himani Chawla6d2ae152020-09-02 13:11:20 +05301542//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1543func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301544 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001545 case MibDatabaseSync:
1546 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301547 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001548 }
1549 case MibDownloadDone:
1550 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301551 dh.processMibDownloadDoneEvent(devEvent)
1552
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001553 }
1554 case UniUnlockStateDone:
1555 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301556 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001557
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001558 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001559 case OmciAniConfigDone:
1560 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301561 dh.processOmciAniConfigDoneEvent(devEvent)
1562
mpagenko3dbcdd22020-07-22 07:38:45 +00001563 }
mpagenkodff5dda2020-08-28 11:52:01 +00001564 case OmciVlanFilterDone:
1565 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301566 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001567
mpagenkodff5dda2020-08-28 11:52:01 +00001568 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001569 default:
1570 {
Himani Chawla4d908332020-08-31 12:30:20 +05301571 logger.Warnw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001572 }
1573 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001574}
1575
Himani Chawla6d2ae152020-09-02 13:11:20 +05301576func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001577 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301578 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301579 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001580 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301581 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001582 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301583 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301584 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001585 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301586 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001587 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001588 //store UniPort with the System-PortNumber key
1589 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001590 if !dh.reconciling {
1591 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301592 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001593 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1594 } //error logging already within UniPort method
1595 } else {
1596 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1597 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001598 }
1599 }
1600}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001601
mpagenko3af1f032020-06-10 08:53:41 +00001602// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301603func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001604 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301605 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001606 // with following remark:
1607 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1608 // # load on the core
1609
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001610 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001611
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001612 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001613 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301614 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001615 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301616 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001617 if !dh.reconciling {
1618 //maybe also use getter functions on uniPort - perhaps later ...
1619 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1620 } else {
1621 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1622 }
mpagenko3af1f032020-06-10 08:53:41 +00001623 }
1624 }
1625}
1626
1627// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301628func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001629 // compare enableUniPortStateUpdate() above
1630 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1631 for uniNo, uniPort := range dh.uniEntityMap {
1632 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301633 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001634 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301635 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001636 //maybe also use getter functions on uniPort - perhaps later ...
1637 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001638 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001639 }
1640}
1641
1642// ONU_Active/Inactive announcement on system KAFKA bus
1643// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301644func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001645 var de voltha.DeviceEvent
1646 eventContext := make(map[string]string)
1647 //Populating event context
1648 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301649 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001650 if err != nil || parentDevice == nil {
1651 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301652 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001653 }
1654 oltSerialNumber := parentDevice.SerialNumber
1655
1656 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1657 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1658 eventContext["serial-number"] = dh.device.SerialNumber
1659 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301660 eventContext["device_id"] = aDeviceID
1661 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001662 logger.Debugw("prepare ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301663 log.Fields{"DeviceId": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001664
1665 /* Populating device event body */
1666 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301667 de.ResourceId = aDeviceID
1668 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001669 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1670 de.Description = fmt.Sprintf("%s Event - %s - %s",
1671 cEventObjectType, cOnuActivatedEvent, "Raised")
1672 } else {
1673 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1674 de.Description = fmt.Sprintf("%s Event - %s - %s",
1675 cEventObjectType, cOnuActivatedEvent, "Cleared")
1676 }
1677 /* Send event to KAFKA */
1678 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1679 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301680 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001681 }
1682 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301683 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001684}
1685
Himani Chawla4d908332020-08-31 12:30:20 +05301686// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301687func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001688 chLSFsm := make(chan Message, 2048)
1689 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301690 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001691 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001692 sFsmName = "LockStateFSM"
1693 } else {
divyadesai4d299552020-08-18 07:13:49 +00001694 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001695 sFsmName = "UnLockStateFSM"
1696 }
mpagenko3af1f032020-06-10 08:53:41 +00001697
Himani Chawla6d2ae152020-09-02 13:11:20 +05301698 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001699 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001700 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001701 return
1702 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301703 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001704 sFsmName, dh.deviceID, chLSFsm)
1705 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301706 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001707 dh.pLockStateFsm = pLSFsm
1708 } else {
1709 dh.pUnlockStateFsm = pLSFsm
1710 }
1711 dh.runUniLockFsm(aAdminState)
1712 } else {
divyadesai4d299552020-08-18 07:13:49 +00001713 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001714 }
1715}
1716
1717// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301718func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001719 /* Uni Port lock/unlock procedure -
1720 ***** should run via 'adminDone' state and generate the argument requested event *****
1721 */
1722 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301723 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001724 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1725 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1726 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001727 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301728 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001729 }
1730 } else {
1731 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1732 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1733 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001734 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301735 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001736 }
1737 }
1738 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001739 if pLSStatemachine.Is(uniStDisabled) {
1740 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001741 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1742 // maybe try a FSM reset and then again ... - TODO!!!
1743 } else {
1744 /***** LockStateFSM started */
1745 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001746 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001747 }
1748 } else {
1749 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001750 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001751 // maybe try a FSM reset and then again ... - TODO!!!
1752 }
1753 } else {
divyadesai4d299552020-08-18 07:13:49 +00001754 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001755 // maybe try a FSM reset and then again ... - TODO!!!
1756 }
1757}
1758
Himani Chawla6d2ae152020-09-02 13:11:20 +05301759//setBackend provides a DB backend for the specified path on the existing KV client
1760func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001761 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1762 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001763 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001764 kvbackend := &db.Backend{
1765 Client: dh.pOpenOnuAc.kvClient,
1766 StoreType: dh.pOpenOnuAc.KVStoreType,
1767 /* address config update acc. to [VOL-2736] */
1768 Address: addr,
1769 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1770 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001771
mpagenkoaf801632020-07-03 10:00:42 +00001772 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001773}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301774func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301775 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001776
mpagenkodff5dda2020-08-28 11:52:01 +00001777 for _, field := range flow.GetOfbFields(apFlowItem) {
1778 switch field.Type {
1779 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1780 {
1781 logger.Debugw("FlowAdd type EthType", log.Fields{"device-id": dh.deviceID,
1782 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1783 }
1784 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1785 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301786 *loIPProto = field.GetIpProto()
mpagenkodff5dda2020-08-28 11:52:01 +00001787 logger.Debugw("FlowAdd type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301788 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1789 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001790 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1791 // avoids installing invalid EVTOCD rule
1792 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1793 log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301794 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1795 return
mpagenkodff5dda2020-08-28 11:52:01 +00001796 }
1797 }
1798 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1799 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301800 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001801 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301802 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001803 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301804 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001805 }
1806 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301807 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001808 }
1809 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1810 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301811 *loAddPcp = uint8(field.GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001812 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1813 "PCP": loAddPcp})
1814 }
1815 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1816 {
1817 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1818 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1819 }
1820 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1821 {
1822 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1823 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1824 }
1825 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1826 {
1827 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1828 "IPv4-DST": field.GetIpv4Dst()})
1829 }
1830 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1831 {
1832 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1833 "IPv4-SRC": field.GetIpv4Src()})
1834 }
1835 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1836 {
1837 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1838 "Metadata": field.GetTableMetadata()})
1839 }
1840 /*
1841 default:
1842 {
1843 //all other entires ignored
1844 }
1845 */
1846 }
1847 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301848}
mpagenkodff5dda2020-08-28 11:52:01 +00001849
Himani Chawla6d2ae152020-09-02 13:11:20 +05301850func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001851 for _, action := range flow.GetActions(apFlowItem) {
1852 switch action.Type {
1853 /* not used:
1854 case of.OfpActionType_OFPAT_OUTPUT:
1855 {
1856 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1857 "Output": action.GetOutput()})
1858 }
1859 */
1860 case of.OfpActionType_OFPAT_PUSH_VLAN:
1861 {
1862 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1863 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1864 }
1865 case of.OfpActionType_OFPAT_SET_FIELD:
1866 {
1867 pActionSetField := action.GetSetField()
1868 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
1869 logger.Warnw("FlowAdd action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
1870 "OxcmClass": pActionSetField.Field.OxmClass})
1871 }
1872 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05301873 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001874 logger.Debugw("FlowAdd Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301875 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001876 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05301877 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001878 logger.Debugw("FlowAdd Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301879 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00001880 } else {
1881 logger.Warnw("FlowAdd action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
1882 "Type": pActionSetField.Field.GetOfbField().Type})
1883 }
1884 }
1885 /*
1886 default:
1887 {
1888 //all other entires ignored
1889 }
1890 */
1891 }
1892 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05301893}
1894
1895//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05301896func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05301897 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
1898 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
1899 var loAddPcp, loSetPcp uint8
1900 var loIPProto uint32
1901 /* the TechProfileId is part of the flow Metadata - compare also comment within
1902 * OLT-Adapter:openolt_flowmgr.go
1903 * Metadata 8 bytes:
1904 * Most Significant 2 Bytes = Inner VLAN
1905 * Next 2 Bytes = Tech Profile ID(TPID)
1906 * Least Significant 4 Bytes = Port ID
1907 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
1908 * subscriber related flows.
1909 */
1910
1911 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
1912 if metadata == 0 {
1913 logger.Debugw("FlowAdd invalid metadata - abort",
1914 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001915 return fmt.Errorf("flowAdd invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05301916 }
1917 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
1918 logger.Debugw("FlowAdd TechProfileId", log.Fields{"device-id": dh.deviceID, "TP-Id": loTpID})
1919
1920 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
1921 if loIPProto == 2 {
1922 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1923 // avoids installing invalid EVTOCD rule
1924 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1925 log.Fields{"device-id": dh.deviceID,
1926 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
1927 return nil
1928 }
1929 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00001930
1931 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1932 logger.Errorw("FlowAdd aborted - SetVlanId undefined, but MatchVid set", log.Fields{
1933 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
1934 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
1935 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
1936 //TODO!!: Use DeviceId within the error response to rwCore
1937 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001938 return fmt.Errorf("flowAdd Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001939 }
1940 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
1941 logger.Debugw("FlowAdd vlan-any/copy", log.Fields{"device-id": dh.deviceID})
1942 loSetVlan = loMatchVlan //both 'transparent' (copy any)
1943 } else {
1944 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
1945 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1946 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05301947 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001948 }
1949 logger.Debugw("FlowAdd vlan-set", log.Fields{"device-id": dh.deviceID})
1950 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301951 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001952 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00001953 }
1954 return dh.createVlanFilterFsm(apUniPort,
1955 loTpID, loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
1956}
1957
Himani Chawla26e555c2020-08-31 12:30:20 +05301958// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
Himani Chawla6d2ae152020-09-02 13:11:20 +05301959func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort,
mpagenkodff5dda2020-08-28 11:52:01 +00001960 aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
1961 chVlanFilterFsm := make(chan Message, 2048)
1962
Himani Chawla6d2ae152020-09-02 13:11:20 +05301963 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00001964 if pDevEntry == nil {
1965 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301966 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001967 }
1968
1969 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
1970 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", dh.deviceID, chVlanFilterFsm,
1971 dh.pOpenOnuAc.AcceptIncrementalEvto, aMatchVlan, aSetVlan, aSetPcp)
1972 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05301973 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001974 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1975 if pVlanFilterStatemachine != nil {
1976 if pVlanFilterStatemachine.Is(vlanStDisabled) {
1977 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
1978 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301979 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001980 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301981 /***** UniVlanConfigFsm started */
1982 logger.Debugw("UniVlanConfigFsm started", log.Fields{
1983 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
1984 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00001985 } else {
1986 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
1987 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301988 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001989 }
1990 } else {
1991 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
1992 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301993 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001994 }
1995 } else {
1996 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
1997 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05301998 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001999 }
2000 return nil
2001}
2002
2003//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302004func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002005 //TODO!! verify and start pending flow configuration
2006 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2007 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302008 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002009 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2010 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2011 if pVlanFilterStatemachine != nil {
2012 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2013 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2014 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2015 } else {
2016 /***** UniVlanConfigFsm continued */
2017 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2018 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2019 "UniPort": apUniPort.portNo})
2020 }
2021 } else {
2022 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2023 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2024 }
2025 } else {
2026 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2027 "device-id": dh.deviceID})
2028 }
2029
2030 } // else: nothing to do
2031}
2032
2033//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2034// 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 +05302035func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002036 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2037 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2038 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302039 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002040}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002041
2042//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2043//available for potential reconcilement
2044
2045func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2046
2047 if dh.reconciling {
2048 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2049 return nil
2050 }
2051 logger.Debugw("Store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2052
2053 pDevEntry := dh.getOnuDeviceEntry(true)
2054 if pDevEntry == nil {
2055 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2056 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2057 }
2058 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2059
2060 pDevEntry.lockOnuKVStoreMutex()
2061 defer pDevEntry.unlockOnuKVStoreMutex()
2062
2063 // deadline context to ensure completion of background routines waited for
2064 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2065 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
2066 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2067
2068 pDevEntry.resetKvProcessingErrorIndication()
2069 var wg sync.WaitGroup
2070 wg.Add(1) // for the 1 go routine to finish
2071
2072 go pDevEntry.updateOnuKvStore(dctx, &wg)
2073 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
2074
2075 return pDevEntry.getKvProcessingErrorIndication()
2076}
2077
2078func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup) {
2079 defer cancel() //ensure termination of context (may be pro forma)
2080 wg.Wait()
2081 logger.Debug("WaitGroup processing completed")
2082
2083}
2084
2085func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2086 var errStr string = ""
2087 for _, err := range errS {
2088 if err != nil {
2089 errStr = errStr + err.Error() + " "
2090 }
2091 }
2092 if errStr != "" {
2093 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2094 }
2095 return nil
2096}