blob: ee8e1b37c13c2993a7bb735bf7d4bd30cddd6615 [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 {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000499 logger.Debugw("FlowUpdateIncremental started", log.Fields{"deviceId": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000500
501 //Remove flows
502 if apOfFlowChanges.ToRemove != nil {
503 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
504 logger.Debugw("incremental flow item remove", log.Fields{"deviceId": dh.deviceID,
505 "Item": flowItem})
506 }
507 }
508 if apOfFlowChanges.ToAdd != nil {
509 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
510 if flowItem.GetCookie() == 0 {
511 logger.Debugw("incremental flow add - no cookie - ignore", log.Fields{
512 "deviceId": dh.deviceID})
513 continue
514 }
515 flowInPort := flow.GetInPort(flowItem)
516 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
517 logger.Errorw("flow inPort invalid", log.Fields{"deviceID": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518 return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000519 } else if flowInPort == dh.ponPortNumber {
520 //this is some downstream flow
521 logger.Debugw("incremental flow ignore downstream", log.Fields{
522 "deviceId": dh.deviceID, "inPort": flowInPort})
523 continue
524 } else {
525 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530526 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000527 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
528 loUniPort = uniPort
529 } else {
530 logger.Errorw("flow inPort not found in UniPorts",
531 log.Fields{"deviceID": dh.deviceID, "inPort": flowInPort})
532 return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
533 }
534 flowOutPort := flow.GetOutPort(flowItem)
535 logger.Debugw("incremental flow-add port indications", log.Fields{
536 "deviceId": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
537 "uniPortName": loUniPort.name})
538 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
539 //abort processing in error case
540 if err != nil {
541 return err
542 }
543 }
544 }
545 }
546 return nil
547}
548
Himani Chawla6d2ae152020-09-02 13:11:20 +0530549//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530550func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000551 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000552
mpagenko3af1f032020-06-10 08:53:41 +0000553 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly - inblock
554 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
555 if dh.deviceReason != "omci-admin-lock" {
556 // disable UNI ports/ONU
557 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
558 // here the result of the processing is not checked (trusted in background) *****
559 if dh.pLockStateFsm == nil {
560 dh.createUniLockFsm(true, UniAdminStateDone)
561 } else { //LockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +0530562 dh.pLockStateFsm.setSuccessEvent(UniAdminStateDone)
mpagenko3af1f032020-06-10 08:53:41 +0000563 dh.runUniLockFsm(true)
564 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000565 //VOL-3493/VOL-3495: postpone setting of deviceReason, conn- and operStatus until all omci-related communication regarding
566 //device disabling has finished successfully
ozgecanetsiafce57b12020-05-25 14:39:35 +0300567 }
568}
569
Himani Chawla6d2ae152020-09-02 13:11:20 +0530570//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530571func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000572 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000573
574 // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...(like python code)
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000575 logger.Debugw("call DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
576 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300577 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
578 voltha.OperStatus_ACTIVE); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000579 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000580 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300581 }
582
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000583 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
584 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000585 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000586 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300587 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000588 dh.deviceReason = "onu-reenabled"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000589
590 // enable ONU/UNI ports
591 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
592 // here the result of the processing is not checked (trusted in background) *****
593 if dh.pUnlockStateFsm == nil {
594 dh.createUniLockFsm(false, UniAdminStateDone)
595 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +0530596 dh.pUnlockStateFsm.setSuccessEvent(UniAdminStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000597 dh.runUniLockFsm(false)
598 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300599}
600
Himani Chawla6d2ae152020-09-02 13:11:20 +0530601func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000602 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
603
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000604 pDevEntry := dh.getOnuDeviceEntry(true)
605 if pDevEntry == nil {
606 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
607 return
608 }
609 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000610 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
611 dh.reconciling = false
612 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000613 }
Himani Chawla4d908332020-08-31 12:30:20 +0530614 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000615 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
616 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
617 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
618 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530619 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000620}
621
Himani Chawla6d2ae152020-09-02 13:11:20 +0530622func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000623 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
624
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000625 pDevEntry := dh.getOnuDeviceEntry(true)
626 if pDevEntry == nil {
627 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
628 return
629 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000630
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000631 dh.pOnuTP.lockTpProcMutex()
632 defer dh.pOnuTP.unlockTpProcMutex()
633
634 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000635 // deadline context to ensure completion of background routines waited for
636 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
637 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
638 dctx, cancel := context.WithDeadline(context.Background(), deadline)
639
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000640 dh.pOnuTP.resetTpProcessingErrorIndication()
641
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000642 var wg sync.WaitGroup
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000643 wg.Add(1) // for the 1 go routine to finish
644 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPath, &wg)
645 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
646
647 if err := dh.pOnuTP.getTpProcessingErrorIndication(); err != nil {
648 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
649 }
650 }
651}
652
653func (dh *deviceHandler) reconcileDeviceFlowConfig() {
654 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
655
656 pDevEntry := dh.getOnuDeviceEntry(true)
657 if pDevEntry == nil {
658 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000659 return
660 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000661 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
662 var uniPort *onuUniPort
663 var exist bool
664 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
665 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
666 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "deviceID": dh.deviceID})
667 return
668 }
669 for _, flowData := range uniData.PersFlowParams {
670 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
671 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.TpID, uint16(flowData.MatchVid),
672 uint16(flowData.SetVid), uint8(flowData.SetPcp)); err != nil {
673 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
674 }
675
676 } else {
677 if err := dh.createVlanFilterFsm(uniPort, flowData.TpID, uint16(flowData.MatchVid), uint16(flowData.SetVid),
678 uint8(flowData.SetPcp), OmciVlanFilterDone); err != nil {
679 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
680 }
681 }
682 }
683 }
684}
685
686func (dh *deviceHandler) reconcileMetrics() {
687 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
688
689 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000690 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000691}
692
Himani Chawla6d2ae152020-09-02 13:11:20 +0530693func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000694 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000695
696 pDevEntry := dh.getOnuDeviceEntry(true)
697 if pDevEntry == nil {
698 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
699 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000700 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000701 pDevEntry.lockOnuKVStoreMutex()
702 defer pDevEntry.unlockOnuKVStoreMutex()
703
704 // deadline context to ensure completion of background routines waited for
705 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
706 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
707 dctx, cancel := context.WithDeadline(context.Background(), deadline)
708
709 pDevEntry.resetKvProcessingErrorIndication()
710
711 var wg sync.WaitGroup
712 wg.Add(1) // for the 1 go routine to finish
713 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
714 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
715
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000716 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000717 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000718}
719
Himani Chawla6d2ae152020-09-02 13:11:20 +0530720func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000721 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300722 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000723 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000724 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300725 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530726 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530727 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
728 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
729 return err
730 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000731 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
732 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300733 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
734 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000735 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000736 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300737 return err
738 }
739 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting-onu"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000740 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000741 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300742 return err
743 }
744 dh.deviceReason = "rebooting-onu"
745 return nil
746}
747
Himani Chawla6d2ae152020-09-02 13:11:20 +0530748// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000749// #####################################################################################
750
751// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530752// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000753
Himani Chawla6d2ae152020-09-02 13:11:20 +0530754func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000755 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})
756}
757
758// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530759func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000760
761 logger.Debug("doStateInit-started")
762 var err error
763
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000764 // populate what we know. rest comes later after mib sync
765 dh.device.Root = false
766 dh.device.Vendor = "OpenONU"
767 dh.device.Model = "go"
768 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000769 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000770
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000771 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000772
773 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530774 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000775 } else {
776 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
777 log.Fields{"device-id": dh.deviceID})
778 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000779
Himani Chawla4d908332020-08-31 12:30:20 +0530780 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000781 dh.ponPortNumber = dh.device.ParentPortNo
782
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000783 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
784 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
785 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000786 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000787 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530788 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000789
790 /*
791 self._pon = PonPort.create(self, self._pon_port_number)
792 self._pon.add_peer(self.parent_id, self._pon_port_number)
793 self.logger.debug('adding-pon-port-to-agent',
794 type=self._pon.get_port().type,
795 admin_state=self._pon.get_port().admin_state,
796 oper_status=self._pon.get_port().oper_status,
797 )
798 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000799 if !dh.reconciling {
800 logger.Debugw("adding-pon-port", log.Fields{"deviceID": dh.deviceID, "ponPortNo": dh.ponPortNumber})
801 var ponPortNo uint32 = 1
802 if dh.ponPortNumber != 0 {
803 ponPortNo = dh.ponPortNumber
804 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000805
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000806 pPonPort := &voltha.Port{
807 PortNo: ponPortNo,
808 Label: fmt.Sprintf("pon-%d", ponPortNo),
809 Type: voltha.Port_PON_ONU,
810 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530811 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000812 PortNo: ponPortNo}}, // Peer port is parent's port number
813 }
814 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
815 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
816 e.Cancel(err)
817 return
818 }
819 } else {
820 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000821 }
822 logger.Debug("doStateInit-done")
823}
824
825// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530826func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000827
828 logger.Debug("postInit-started")
829 var err error
830 /*
831 dh.Client = oop.NewOpenoltClient(dh.clientCon)
832 dh.pTransitionMap.Handle(ctx, GrpcConnected)
833 return nil
834 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530835 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
836 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000837 e.Cancel(err)
838 return
839 }
840
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000841 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530842 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000843 // reconcilement will be continued after mib download is done
844 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000845 /*
846 ############################################################################
847 # Setup Alarm handler
848 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
849 device.serial_number)
850 ############################################################################
851 # Setup PM configuration for this device
852 # Pass in ONU specific options
853 kwargs = {
854 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
855 'heartbeat': self.heartbeat,
856 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
857 }
858 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
859 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
860 self.logical_device_id, device.serial_number,
861 grouped=True, freq_override=False, **kwargs)
862 pm_config = self._pm_metrics.make_proto()
863 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
864 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
865 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
866
867 # Note, ONU ID and UNI intf set in add_uni_port method
868 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
869 ani_ports=[self._pon])
870
871 # Code to Run OMCI Test Action
872 kwargs_omci_test_action = {
873 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
874 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
875 }
876 serial_number = device.serial_number
877 self._test_request = OmciTestRequest(self.core_proxy,
878 self.omci_agent, self.device_id,
879 AniG, serial_number,
880 self.logical_device_id,
881 exclusive=False,
882 **kwargs_omci_test_action)
883
884 self.enabled = True
885 else:
886 self.logger.info('onu-already-activated')
887 */
888 logger.Debug("postInit-done")
889}
890
891// doStateConnected get the device info and update to voltha core
892// for comparison of the original method (not that easy to uncomment): compare here:
893// voltha-openolt-adapter/adaptercore/device_handler.go
894// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530895func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000896
897 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530898 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000899 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000900 logger.Debug("doStateConnected-done")
901}
902
903// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530904func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000905
906 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530907 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000908 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000909 logger.Debug("doStateUp-done")
910
911 /*
912 // Synchronous call to update device state - this method is run in its own go routine
913 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
914 voltha.OperStatus_ACTIVE); err != nil {
915 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
916 return err
917 }
918 return nil
919 */
920}
921
922// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +0530923func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000924
925 logger.Debug("doStateDown-started")
926 var err error
927
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000928 device := dh.device
929 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000930 /*TODO: needs to handle error scenarios */
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000931 logger.Error("Failed to fetch handler device")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000932 e.Cancel(err)
933 return
934 }
935
936 cloned := proto.Clone(device).(*voltha.Device)
937 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
938 /*
939 // Update the all ports state on that device to disable
940 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
941 logger.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
942 return er
943 }
944
945 //Update the device oper state and connection status
946 cloned.OperStatus = voltha.OperStatus_UNKNOWN
947 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
948 dh.device = cloned
949
950 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
951 logger.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
952 return er
953 }
954
955 //get the child device for the parent device
956 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
957 if err != nil {
958 logger.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
959 return err
960 }
961 for _, onuDevice := range onuDevices.Items {
962
963 // Update onu state as down in onu adapter
964 onuInd := oop.OnuIndication{}
965 onuInd.OperState = "down"
966 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
967 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
968 if er != nil {
969 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
970 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
971 //Do not return here and continue to process other ONUs
972 }
973 }
974 // * Discovered ONUs entries need to be cleared , since after OLT
975 // is up, it starts sending discovery indications again* /
976 dh.discOnus = sync.Map{}
977 logger.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
978 return nil
979 */
Himani Chawla4d908332020-08-31 12:30:20 +0530980 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000982 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000983}
984
Himani Chawla6d2ae152020-09-02 13:11:20 +0530985// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000986// #################################################################################
987
988// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530989// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000990
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000991//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +0530992func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +0000993 dh.lockDevice.RLock()
994 pOnuDeviceEntry := dh.pOnuOmciDevice
995 if aWait && pOnuDeviceEntry == nil {
996 //keep the read sema short to allow for subsequent write
997 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +0000998 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000999 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1000 // so it might be needed to wait here for that event with some timeout
1001 select {
1002 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001003 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001004 return nil
1005 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001006 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001007 // if written now, we can return the written value without sema
1008 return dh.pOnuOmciDevice
1009 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001010 }
mpagenko3af1f032020-06-10 08:53:41 +00001011 dh.lockDevice.RUnlock()
1012 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001013}
1014
Himani Chawla6d2ae152020-09-02 13:11:20 +05301015//setOnuDeviceEntry sets the ONU device entry within the handler
1016func (dh *deviceHandler) setOnuDeviceEntry(
1017 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001018 dh.lockDevice.Lock()
1019 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001020 dh.pOnuOmciDevice = apDeviceEntry
1021 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001022}
1023
Himani Chawla6d2ae152020-09-02 13:11:20 +05301024//addOnuDeviceEntry creates a new ONU device or returns the existing
1025func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001026 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001027
Himani Chawla6d2ae152020-09-02 13:11:20 +05301028 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001029 if deviceEntry == nil {
1030 /* costum_me_map in python code seems always to be None,
1031 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1032 /* also no 'clock' argument - usage open ...*/
1033 /* and no alarm_db yet (oo.alarm_db) */
Himani Chawla6d2ae152020-09-02 13:11:20 +05301034 deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
mpagenkoaf801632020-07-03 10:00:42 +00001035 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001036 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001037 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
Himani Chawla6d2ae152020-09-02 13:11:20 +05301038 onuTechProfProc := newOnuUniTechProf(ctx, dh.deviceID, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001039 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301040 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001041 // fire deviceEntry ready event to spread to possibly waiting processing
1042 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001043 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001044 } else {
divyadesai4d299552020-08-18 07:13:49 +00001045 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001046 }
1047 // might be updated with some error handling !!!
1048 return nil
1049}
1050
1051// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301052func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001053 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1054 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1055
1056 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001057
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001058 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001059 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1060 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001061 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1062 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1063 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1064 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1065 }
1066 } else {
1067 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1068 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001070 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1071 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1072 // 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 +00001073 // 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 +00001074 // so let's just try to keep it simple ...
1075 /*
1076 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1077 if err != nil || device == nil {
1078 //TODO: needs to handle error scenarios
1079 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1080 return errors.New("Voltha Device not found")
1081 }
1082 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001083
Himani Chawla6d2ae152020-09-02 13:11:20 +05301084 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001085 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301086 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301087 return err
1088 }
mpagenko3af1f032020-06-10 08:53:41 +00001089 } else {
divyadesai4d299552020-08-18 07:13:49 +00001090 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001091 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001092 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001093 if !dh.reconciling {
1094 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1095 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1096 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1097 }
1098 } else {
1099 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1100 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001101 }
mpagenko3af1f032020-06-10 08:53:41 +00001102 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001103
1104 /* this might be a good time for Omci Verify message? */
1105 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301106 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001107 dh.device.Id, pDevEntry.PDevOmciCC,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108 true, true) //eclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301109 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001110
1111 /* give the handler some time here to wait for the OMCi verification result
1112 after Timeout start and try MibUpload FSM anyway
1113 (to prevent stopping on just not supported OMCI verification from ONU) */
1114 select {
1115 case <-time.After(2 * time.Second):
1116 logger.Warn("omci start-verification timed out (continue normal)")
1117 case testresult := <-verifyExec:
1118 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1119 }
1120
1121 /* In py code it looks earlier (on activate ..)
1122 # Code to Run OMCI Test Action
1123 kwargs_omci_test_action = {
1124 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1125 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1126 }
1127 serial_number = device.serial_number
1128 self._test_request = OmciTestRequest(self.core_proxy,
1129 self.omci_agent, self.device_id,
1130 AniG, serial_number,
1131 self.logical_device_id,
1132 exclusive=False,
1133 **kwargs_omci_test_action)
1134 ...
1135 # Start test requests after a brief pause
1136 if not self._test_request_started:
1137 self._test_request_started = True
1138 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1139 reactor.callLater(tststart, self._test_request.start_collector)
1140
1141 */
1142 /* which is then: in omci_test_request.py : */
1143 /*
1144 def start_collector(self, callback=None):
1145 """
1146 Start the collection loop for an adapter if the frequency > 0
1147
1148 :param callback: (callable) Function to call to collect PM data
1149 """
1150 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1151 if callback is None:
1152 callback = self.perform_test_omci
1153
1154 if self.lc is None:
1155 self.lc = LoopingCall(callback)
1156
1157 if self.default_freq > 0:
1158 self.lc.start(interval=self.default_freq / 10)
1159
1160 def perform_test_omci(self):
1161 """
1162 Perform the initial test request
1163 """
1164 ani_g_entities = self._device.configuration.ani_g_entities
1165 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1166 is not None else None
1167 self._entity_id = ani_g_entities_ids[0]
1168 self.logger.info('perform-test', entity_class=self._entity_class,
1169 entity_id=self._entity_id)
1170 try:
1171 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1172 result = yield self._device.omci_cc.send(frame)
1173 if not result.fields['omci_message'].fields['success_code']:
1174 self.logger.info('Self-Test Submitted Successfully',
1175 code=result.fields[
1176 'omci_message'].fields['success_code'])
1177 else:
1178 raise TestFailure('Test Failure: {}'.format(
1179 result.fields['omci_message'].fields['success_code']))
1180 except TimeoutError as e:
1181 self.deferred.errback(failure.Failure(e))
1182
1183 except Exception as e:
1184 self.logger.exception('perform-test-Error', e=e,
1185 class_id=self._entity_class,
1186 entity_id=self._entity_id)
1187 self.deferred.errback(failure.Failure(e))
1188
1189 */
1190
1191 // PM related heartbeat??? !!!TODO....
1192 //self._heartbeat.enabled = True
1193
mpagenko1cc3cb42020-07-27 15:24:38 +00001194 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1195 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1196 * 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 +05301197 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001198 */
1199 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001200 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001201 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001202 if pMibUlFsm.Is(ulStDisabled) {
1203 if err := pMibUlFsm.Event(ulEvStart); err != nil {
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001204 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001205 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301206 }
1207 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1208 //Determine ONU status and start/re-start MIB Synchronization tasks
1209 //Determine if this ONU has ever synchronized
1210 if true { //TODO: insert valid check
1211 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
1212 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001213 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001214 }
Himani Chawla4d908332020-08-31 12:30:20 +05301215 } else {
1216 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
1217 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001218 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301219 }
1220 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1221 //Examine the MIB Data Sync
1222 // callbacks to be handled:
1223 // Event(ulEvSuccess)
1224 // Event(ulEvTimeout)
1225 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001226 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001227 } else {
1228 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current())})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001229 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001230 }
1231 } else {
divyadesai4d299552020-08-18 07:13:49 +00001232 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001233 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001234 }
1235 return nil
1236}
1237
Himani Chawla6d2ae152020-09-02 13:11:20 +05301238func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001239 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1240 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001241 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001242 //stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
Himani Chawla6d2ae152020-09-02 13:11:20 +05301243 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001244 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001245 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001246 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001247 }
1248
1249 switch dh.deviceReason {
1250 case "starting-openomci":
1251 { //MIBSync FSM may run
1252 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1253 if pMibUlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301254 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
mpagenko3af1f032020-06-10 08:53:41 +00001255 }
1256 }
1257 case "discovery-mibsync-complete":
1258 { //MibDownload may run
1259 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1260 if pMibDlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301261 _ = pMibDlFsm.Event(dlEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001262 }
1263 }
1264 default:
mpagenko3dbcdd22020-07-22 07:38:45 +00001265 {
1266 //port lock/unlock FSM's may be active
mpagenko3af1f032020-06-10 08:53:41 +00001267 if dh.pUnlockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301268 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001269 }
1270 if dh.pLockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301271 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001272 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001273 //techProfile related PonAniConfigFsm FSM may be active
1274 // maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1275 if dh.pOnuTP.pAniConfigFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301276 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +00001277 }
mpagenkodff5dda2020-08-28 11:52:01 +00001278 for _, uniPort := range dh.uniEntityMap {
1279 //reset the TechProfileConfig Done state for all (active) UNI's
Himani Chawla26e555c2020-08-31 12:30:20 +05301280 dh.pOnuTP.setConfigDone(uniPort.uniID, false)
1281 // reset the possibly existing VlanConfigFsm
1282 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00001283 //VlanFilterFsm exists and was already started
1284 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1285 if pVlanFilterStatemachine != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301286 _ = pVlanFilterStatemachine.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +00001287 }
1288 }
1289 }
mpagenko3af1f032020-06-10 08:53:41 +00001290 }
1291 //TODO!!! care about PM/Alarm processing once started
1292 }
1293 //TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
Himani Chawla4d908332020-08-31 12:30:20 +05301294 // (mainly the still separate 'Event states')
mpagenko3af1f032020-06-10 08:53:41 +00001295 // so it is questionable, how this is resolved after some possible re-enable
1296 // assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
1297
1298 //stop/remove(?) the device entry
Himani Chawla6d2ae152020-09-02 13:11:20 +05301299 _ = pDevEntry.stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
mpagenko3af1f032020-06-10 08:53:41 +00001300
1301 //TODO!!! remove existing traffic profiles
1302 /* from py code, if TP's exist, remove them - not yet implemented
1303 self._tp = dict()
1304 # Let TP download happen again
1305 for uni_id in self._tp_service_specific_task:
1306 self._tp_service_specific_task[uni_id].clear()
1307 for uni_id in self._tech_profile_download_done:
1308 self._tech_profile_download_done[uni_id].clear()
1309 */
1310
1311 dh.disableUniPortStateUpdate()
1312
1313 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001314 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001315 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001316 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001317 // abort: system behavior is just unstable ...
1318 return err
1319 }
1320 dh.deviceReason = "stopping-openomci"
1321
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001322 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1323 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001324 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1325 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001326 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001327 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001328 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001329 // abort: system behavior is just unstable ...
1330 return err
1331 }
1332 } else {
divyadesai4d299552020-08-18 07:13:49 +00001333 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001334 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001335 return nil
1336}
1337
Himani Chawla6d2ae152020-09-02 13:11:20 +05301338func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301339 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1340 if !dh.reconciling {
1341 //initiate DevStateUpdate
1342 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1343 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1344 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
1345 "device-id": dh.deviceID, "error": err})
1346 } else {
1347 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
1348 }
1349 } else {
1350 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1351 log.Fields{"device-id": dh.deviceID})
1352 }
1353 //set internal state anyway - as it was done
1354 dh.deviceReason = "discovery-mibsync-complete"
1355
1356 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301357 pDevEntry := dh.getOnuDeviceEntry(false)
1358 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301359 for _, mgmtEntityID := range unigInstKeys {
1360 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1361 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301362 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301363 i++
1364 }
1365 } else {
1366 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1367 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301368 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301369 for _, mgmtEntityID := range veipInstKeys {
1370 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1371 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301372 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301373 i++
1374 }
1375 } else {
1376 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1377 }
1378 if i == 0 {
1379 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1380 }
1381
1382 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1383 * left the code here as comment in case such processing should prove needed unexpectedly
1384 // Init Uni Ports to Admin locked state
1385 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1386 // *** should generate UniLockStateDone event *****
1387 if dh.pLockStateFsm == nil {
1388 dh.createUniLockFsm(true, UniLockStateDone)
1389 } else { //LockStateFSM already init
1390 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1391 dh.runUniLockFsm(true)
1392 }
1393 }
1394 case UniLockStateDone:
1395 {
1396 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1397 * lockState processing commented out
1398 */
1399 /* Mib download procedure -
1400 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1401 */
1402 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1403 if pMibDlFsm != nil {
1404 if pMibDlFsm.Is(dlStDisabled) {
1405 if err := pMibDlFsm.Event(dlEvStart); err != nil {
1406 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"err": err})
1407 // maybe try a FSM reset and then again ... - TODO!!!
1408 } else {
1409 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1410 // maybe use more specific states here for the specific download steps ...
1411 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
1412 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"err": err})
1413 } else {
1414 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1415 //Begin MIB data download (running autonomously)
1416 }
1417 }
1418 } else {
1419 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current())})
1420 // maybe try a FSM reset and then again ... - TODO!!!
1421 }
1422 /***** Mib download started */
1423 } else {
1424 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1425 }
1426}
1427
Himani Chawla6d2ae152020-09-02 13:11:20 +05301428func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301429 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1430 //initiate DevStateUpdate
1431 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001432 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1433 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301434 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1435 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1436 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1437 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1438 } else {
1439 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1440 }
1441 } else {
1442 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1443 log.Fields{"device-id": dh.deviceID})
1444 }
1445 if !dh.reconciling {
1446 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1447 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1448 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
1449 log.Fields{"device-id": dh.deviceID, "error": err})
1450 } else {
1451 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
1452 }
1453 } else {
1454 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1455 log.Fields{"device-id": dh.deviceID})
1456 }
1457 //set internal state anyway - as it was done
1458 dh.deviceReason = "initial-mib-downloaded"
1459 // *** should generate UniUnlockStateDone event *****
1460 if dh.pUnlockStateFsm == nil {
1461 dh.createUniLockFsm(false, UniUnlockStateDone)
1462 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301463 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301464 dh.runUniLockFsm(false)
1465 }
1466}
1467
Himani Chawla6d2ae152020-09-02 13:11:20 +05301468func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301469 go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
1470
1471 if !dh.reconciling {
1472 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1473 raisedTs := time.Now().UnixNano()
1474 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1475 } else {
1476 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1477 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301478 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001479 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301480 }
1481}
1482
Himani Chawla6d2ae152020-09-02 13:11:20 +05301483func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301484 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1485 // attention: the device reason update is done based on ONU-UNI-Port related activity
1486 // - which may cause some inconsistency
1487 if dh.deviceReason != "tech-profile-config-download-success" {
1488 // which may be the case from some previous actvity on another UNI Port of the ONU
1489 if !dh.reconciling {
1490 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1491 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1492 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
1493 log.Fields{"device-id": dh.deviceID, "error": err})
1494 } else {
1495 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
1496 log.Fields{"device-id": dh.deviceID})
1497 }
1498 } else {
1499 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
1500 log.Fields{"device-id": dh.deviceID})
1501 }
1502 //set internal state anyway - as it was done
1503 dh.deviceReason = "tech-profile-config-download-success"
1504 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001505 if dh.reconciling {
1506 go dh.reconcileDeviceFlowConfig()
1507 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301508}
1509
Himani Chawla6d2ae152020-09-02 13:11:20 +05301510func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301511 logger.Debugw("OmciVlanFilterDone event received",
1512 log.Fields{"device-id": dh.deviceID})
1513 // attention: the device reason update is done based on ONU-UNI-Port related activity
1514 // - which may cause some inconsistency
1515 // yield self.core_proxy.device_reason_update(self.device_id, 'omci-flows-pushed')
1516
1517 if dh.deviceReason != "omci-flows-pushed" {
1518 // which may be the case from some previous actvity on another UNI Port of the ONU
1519 // or even some previous flow add activity on the same port
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001520 if !dh.reconciling {
1521 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1522 logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
1523 log.Fields{"device-id": dh.deviceID, "error": err})
1524 } else {
1525 logger.Infow("updated dev reason to ''omci-flows-pushed'",
1526 log.Fields{"device-id": dh.deviceID})
1527 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301528 } else {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001529 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Himani Chawla26e555c2020-08-31 12:30:20 +05301530 log.Fields{"device-id": dh.deviceID})
1531 }
1532 //set internal state anyway - as it was done
1533 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001534
1535 if dh.reconciling {
1536 go dh.reconcileMetrics()
1537 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301538 }
1539}
1540
Himani Chawla6d2ae152020-09-02 13:11:20 +05301541//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1542func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301543 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001544 case MibDatabaseSync:
1545 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301546 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001547 }
1548 case MibDownloadDone:
1549 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301550 dh.processMibDownloadDoneEvent(devEvent)
1551
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001552 }
1553 case UniUnlockStateDone:
1554 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301555 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001556
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001557 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001558 case OmciAniConfigDone:
1559 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301560 dh.processOmciAniConfigDoneEvent(devEvent)
1561
mpagenko3dbcdd22020-07-22 07:38:45 +00001562 }
mpagenkodff5dda2020-08-28 11:52:01 +00001563 case OmciVlanFilterDone:
1564 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301565 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001566
mpagenkodff5dda2020-08-28 11:52:01 +00001567 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001568 default:
1569 {
Himani Chawla4d908332020-08-31 12:30:20 +05301570 logger.Warnw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001571 }
1572 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573}
1574
Himani Chawla6d2ae152020-09-02 13:11:20 +05301575func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001576 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301577 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301578 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001579 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301580 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001581 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301582 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301583 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001584 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301585 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001586 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001587 //store UniPort with the System-PortNumber key
1588 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001589 if !dh.reconciling {
1590 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301591 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001592 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1593 } //error logging already within UniPort method
1594 } else {
1595 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1596 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001597 }
1598 }
1599}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001600
mpagenko3af1f032020-06-10 08:53:41 +00001601// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301602func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001603 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301604 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001605 // with following remark:
1606 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1607 // # load on the core
1608
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001609 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001610
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001611 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001612 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301613 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001614 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301615 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001616 if !dh.reconciling {
1617 //maybe also use getter functions on uniPort - perhaps later ...
1618 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1619 } else {
1620 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1621 }
mpagenko3af1f032020-06-10 08:53:41 +00001622 }
1623 }
1624}
1625
1626// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301627func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001628 // compare enableUniPortStateUpdate() above
1629 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1630 for uniNo, uniPort := range dh.uniEntityMap {
1631 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301632 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001633 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301634 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001635 //maybe also use getter functions on uniPort - perhaps later ...
1636 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001637 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001638 }
1639}
1640
1641// ONU_Active/Inactive announcement on system KAFKA bus
1642// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301643func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001644 var de voltha.DeviceEvent
1645 eventContext := make(map[string]string)
1646 //Populating event context
1647 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301648 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001649 if err != nil || parentDevice == nil {
1650 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301651 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001652 }
1653 oltSerialNumber := parentDevice.SerialNumber
1654
1655 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1656 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1657 eventContext["serial-number"] = dh.device.SerialNumber
1658 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301659 eventContext["device_id"] = aDeviceID
1660 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001661 logger.Debugw("prepare ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301662 log.Fields{"DeviceId": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001663
1664 /* Populating device event body */
1665 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301666 de.ResourceId = aDeviceID
1667 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001668 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1669 de.Description = fmt.Sprintf("%s Event - %s - %s",
1670 cEventObjectType, cOnuActivatedEvent, "Raised")
1671 } else {
1672 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1673 de.Description = fmt.Sprintf("%s Event - %s - %s",
1674 cEventObjectType, cOnuActivatedEvent, "Cleared")
1675 }
1676 /* Send event to KAFKA */
1677 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1678 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301679 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001680 }
1681 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301682 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001683}
1684
Himani Chawla4d908332020-08-31 12:30:20 +05301685// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301686func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001687 chLSFsm := make(chan Message, 2048)
1688 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301689 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001690 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001691 sFsmName = "LockStateFSM"
1692 } else {
divyadesai4d299552020-08-18 07:13:49 +00001693 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001694 sFsmName = "UnLockStateFSM"
1695 }
mpagenko3af1f032020-06-10 08:53:41 +00001696
Himani Chawla6d2ae152020-09-02 13:11:20 +05301697 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001698 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001699 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001700 return
1701 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301702 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001703 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001704 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301705 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001706 dh.pLockStateFsm = pLSFsm
1707 } else {
1708 dh.pUnlockStateFsm = pLSFsm
1709 }
1710 dh.runUniLockFsm(aAdminState)
1711 } else {
divyadesai4d299552020-08-18 07:13:49 +00001712 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001713 }
1714}
1715
1716// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301717func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001718 /* Uni Port lock/unlock procedure -
1719 ***** should run via 'adminDone' state and generate the argument requested event *****
1720 */
1721 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301722 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001723 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1724 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1725 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001726 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301727 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001728 }
1729 } else {
1730 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1731 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1732 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001733 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301734 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001735 }
1736 }
1737 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001738 if pLSStatemachine.Is(uniStDisabled) {
1739 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001740 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1741 // maybe try a FSM reset and then again ... - TODO!!!
1742 } else {
1743 /***** LockStateFSM started */
1744 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001745 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001746 }
1747 } else {
1748 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001749 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001750 // maybe try a FSM reset and then again ... - TODO!!!
1751 }
1752 } else {
divyadesai4d299552020-08-18 07:13:49 +00001753 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001754 // maybe try a FSM reset and then again ... - TODO!!!
1755 }
1756}
1757
Himani Chawla6d2ae152020-09-02 13:11:20 +05301758//setBackend provides a DB backend for the specified path on the existing KV client
1759func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001760 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1761 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001762 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001763 kvbackend := &db.Backend{
1764 Client: dh.pOpenOnuAc.kvClient,
1765 StoreType: dh.pOpenOnuAc.KVStoreType,
1766 /* address config update acc. to [VOL-2736] */
1767 Address: addr,
1768 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1769 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001770
mpagenkoaf801632020-07-03 10:00:42 +00001771 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001772}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301773func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301774 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001775
mpagenkodff5dda2020-08-28 11:52:01 +00001776 for _, field := range flow.GetOfbFields(apFlowItem) {
1777 switch field.Type {
1778 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1779 {
1780 logger.Debugw("FlowAdd type EthType", log.Fields{"device-id": dh.deviceID,
1781 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1782 }
1783 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1784 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301785 *loIPProto = field.GetIpProto()
mpagenkodff5dda2020-08-28 11:52:01 +00001786 logger.Debugw("FlowAdd type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301787 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1788 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001789 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1790 // avoids installing invalid EVTOCD rule
1791 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1792 log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301793 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1794 return
mpagenkodff5dda2020-08-28 11:52:01 +00001795 }
1796 }
1797 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1798 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301799 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001800 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301801 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001802 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301803 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001804 }
1805 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301806 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001807 }
1808 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1809 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301810 *loAddPcp = uint8(field.GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001811 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1812 "PCP": loAddPcp})
1813 }
1814 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1815 {
1816 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1817 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1818 }
1819 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1820 {
1821 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1822 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1823 }
1824 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1825 {
1826 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1827 "IPv4-DST": field.GetIpv4Dst()})
1828 }
1829 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1830 {
1831 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1832 "IPv4-SRC": field.GetIpv4Src()})
1833 }
1834 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1835 {
1836 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1837 "Metadata": field.GetTableMetadata()})
1838 }
1839 /*
1840 default:
1841 {
1842 //all other entires ignored
1843 }
1844 */
1845 }
1846 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301847}
mpagenkodff5dda2020-08-28 11:52:01 +00001848
Himani Chawla6d2ae152020-09-02 13:11:20 +05301849func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001850 for _, action := range flow.GetActions(apFlowItem) {
1851 switch action.Type {
1852 /* not used:
1853 case of.OfpActionType_OFPAT_OUTPUT:
1854 {
1855 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1856 "Output": action.GetOutput()})
1857 }
1858 */
1859 case of.OfpActionType_OFPAT_PUSH_VLAN:
1860 {
1861 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1862 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1863 }
1864 case of.OfpActionType_OFPAT_SET_FIELD:
1865 {
1866 pActionSetField := action.GetSetField()
1867 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
1868 logger.Warnw("FlowAdd action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
1869 "OxcmClass": pActionSetField.Field.OxmClass})
1870 }
1871 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05301872 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001873 logger.Debugw("FlowAdd Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301874 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001875 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05301876 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001877 logger.Debugw("FlowAdd Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301878 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00001879 } else {
1880 logger.Warnw("FlowAdd action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
1881 "Type": pActionSetField.Field.GetOfbField().Type})
1882 }
1883 }
1884 /*
1885 default:
1886 {
1887 //all other entires ignored
1888 }
1889 */
1890 }
1891 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05301892}
1893
1894//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05301895func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05301896 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
1897 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
1898 var loAddPcp, loSetPcp uint8
1899 var loIPProto uint32
1900 /* the TechProfileId is part of the flow Metadata - compare also comment within
1901 * OLT-Adapter:openolt_flowmgr.go
1902 * Metadata 8 bytes:
1903 * Most Significant 2 Bytes = Inner VLAN
1904 * Next 2 Bytes = Tech Profile ID(TPID)
1905 * Least Significant 4 Bytes = Port ID
1906 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
1907 * subscriber related flows.
1908 */
1909
1910 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
1911 if metadata == 0 {
1912 logger.Debugw("FlowAdd invalid metadata - abort",
1913 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001914 return fmt.Errorf("flowAdd invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05301915 }
1916 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
1917 logger.Debugw("FlowAdd TechProfileId", log.Fields{"device-id": dh.deviceID, "TP-Id": loTpID})
1918
1919 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
1920 if loIPProto == 2 {
1921 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1922 // avoids installing invalid EVTOCD rule
1923 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1924 log.Fields{"device-id": dh.deviceID,
1925 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
1926 return nil
1927 }
1928 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00001929
1930 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1931 logger.Errorw("FlowAdd aborted - SetVlanId undefined, but MatchVid set", log.Fields{
1932 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
1933 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
1934 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
1935 //TODO!!: Use DeviceId within the error response to rwCore
1936 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001937 return fmt.Errorf("flowAdd Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001938 }
1939 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
1940 logger.Debugw("FlowAdd vlan-any/copy", log.Fields{"device-id": dh.deviceID})
1941 loSetVlan = loMatchVlan //both 'transparent' (copy any)
1942 } else {
1943 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
1944 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1945 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05301946 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001947 }
1948 logger.Debugw("FlowAdd vlan-set", log.Fields{"device-id": dh.deviceID})
1949 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301950 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001951 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00001952 }
1953 return dh.createVlanFilterFsm(apUniPort,
1954 loTpID, loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
1955}
1956
Himani Chawla26e555c2020-08-31 12:30:20 +05301957// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
Himani Chawla6d2ae152020-09-02 13:11:20 +05301958func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort,
mpagenkodff5dda2020-08-28 11:52:01 +00001959 aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
1960 chVlanFilterFsm := make(chan Message, 2048)
1961
Himani Chawla6d2ae152020-09-02 13:11:20 +05301962 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00001963 if pDevEntry == nil {
1964 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301965 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001966 }
1967
1968 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
1969 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", dh.deviceID, chVlanFilterFsm,
1970 dh.pOpenOnuAc.AcceptIncrementalEvto, aMatchVlan, aSetVlan, aSetPcp)
1971 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05301972 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001973 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1974 if pVlanFilterStatemachine != nil {
1975 if pVlanFilterStatemachine.Is(vlanStDisabled) {
1976 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
1977 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301978 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001979 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301980 /***** UniVlanConfigFsm started */
1981 logger.Debugw("UniVlanConfigFsm started", log.Fields{
1982 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
1983 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00001984 } else {
1985 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
1986 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301987 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001988 }
1989 } else {
1990 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
1991 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301992 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001993 }
1994 } else {
1995 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
1996 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05301997 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001998 }
1999 return nil
2000}
2001
2002//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302003func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002004 //TODO!! verify and start pending flow configuration
2005 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2006 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302007 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002008 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2009 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2010 if pVlanFilterStatemachine != nil {
2011 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2012 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2013 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2014 } else {
2015 /***** UniVlanConfigFsm continued */
2016 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2017 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2018 "UniPort": apUniPort.portNo})
2019 }
2020 } else {
2021 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2022 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2023 }
2024 } else {
2025 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2026 "device-id": dh.deviceID})
2027 }
2028
2029 } // else: nothing to do
2030}
2031
2032//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2033// 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 +05302034func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002035 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2036 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2037 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302038 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002039}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002040
2041//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2042//available for potential reconcilement
2043
2044func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2045
2046 if dh.reconciling {
2047 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2048 return nil
2049 }
2050 logger.Debugw("Store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2051
2052 pDevEntry := dh.getOnuDeviceEntry(true)
2053 if pDevEntry == nil {
2054 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2055 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2056 }
2057 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2058
2059 pDevEntry.lockOnuKVStoreMutex()
2060 defer pDevEntry.unlockOnuKVStoreMutex()
2061
2062 // deadline context to ensure completion of background routines waited for
2063 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2064 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
2065 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2066
2067 pDevEntry.resetKvProcessingErrorIndication()
2068 var wg sync.WaitGroup
2069 wg.Add(1) // for the 1 go routine to finish
2070
2071 go pDevEntry.updateOnuKvStore(dctx, &wg)
2072 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
2073
2074 return pDevEntry.getKvProcessingErrorIndication()
2075}
2076
2077func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup) {
2078 defer cancel() //ensure termination of context (may be pro forma)
2079 wg.Wait()
2080 logger.Debug("WaitGroup processing completed")
2081
2082}
2083
2084func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2085 var errStr string = ""
2086 for _, err := range errS {
2087 if err != nil {
2088 errStr = errStr + err.Error() + " "
2089 }
2090 }
2091 if errStr != "" {
2092 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2093 }
2094 return nil
2095}