blob: 61ce8dcf1f49cf917604a9d569af37ea1bd0c01d [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
Himani Chawlad96df182020-09-28 11:12:02 +0530321 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530322 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
Himani Chawlad96df182020-09-28 11:12:02 +0530377 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 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
Himani Chawlad96df182020-09-28 11:12:02 +0530433 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530434 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
Himani Chawlad96df182020-09-28 11:12:02 +0530637 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000638 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
Himani Chawlad96df182020-09-28 11:12:02 +0530706 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000707 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 */
Andrea Campanella6515c582020-10-05 11:25:00 +0200931 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
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 {
Andrea Campanella6515c582020-10-05 11:25:00 +02001204 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"deviceId": dh.deviceID, "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 {
Andrea Campanella6515c582020-10-05 11:25:00 +02001212 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"deviceId": dh.deviceID, "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 {
Andrea Campanella6515c582020-10-05 11:25:00 +02001217 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"deviceId": dh.deviceID, "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 {
Andrea Campanella6515c582020-10-05 11:25:00 +02001228 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
1229 "deviceId": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001230 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001231 }
1232 } else {
divyadesai4d299552020-08-18 07:13:49 +00001233 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001234 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001235 }
1236 return nil
1237}
1238
Himani Chawla6d2ae152020-09-02 13:11:20 +05301239func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001240 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1241 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001242 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001243 //stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
Himani Chawla6d2ae152020-09-02 13:11:20 +05301244 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001245 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001246 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001247 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001248 }
1249
1250 switch dh.deviceReason {
1251 case "starting-openomci":
1252 { //MIBSync FSM may run
1253 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1254 if pMibUlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301255 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
mpagenko3af1f032020-06-10 08:53:41 +00001256 }
1257 }
1258 case "discovery-mibsync-complete":
1259 { //MibDownload may run
1260 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1261 if pMibDlFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301262 _ = pMibDlFsm.Event(dlEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001263 }
1264 }
1265 default:
mpagenko3dbcdd22020-07-22 07:38:45 +00001266 {
1267 //port lock/unlock FSM's may be active
mpagenko3af1f032020-06-10 08:53:41 +00001268 if dh.pUnlockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301269 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001270 }
1271 if dh.pLockStateFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301272 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001273 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001274 //techProfile related PonAniConfigFsm FSM may be active
1275 // maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1276 if dh.pOnuTP.pAniConfigFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301277 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +00001278 }
mpagenkodff5dda2020-08-28 11:52:01 +00001279 for _, uniPort := range dh.uniEntityMap {
1280 //reset the TechProfileConfig Done state for all (active) UNI's
Himani Chawla26e555c2020-08-31 12:30:20 +05301281 dh.pOnuTP.setConfigDone(uniPort.uniID, false)
1282 // reset the possibly existing VlanConfigFsm
1283 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00001284 //VlanFilterFsm exists and was already started
1285 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1286 if pVlanFilterStatemachine != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301287 _ = pVlanFilterStatemachine.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +00001288 }
1289 }
1290 }
mpagenko3af1f032020-06-10 08:53:41 +00001291 }
1292 //TODO!!! care about PM/Alarm processing once started
1293 }
1294 //TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
Himani Chawla4d908332020-08-31 12:30:20 +05301295 // (mainly the still separate 'Event states')
mpagenko3af1f032020-06-10 08:53:41 +00001296 // so it is questionable, how this is resolved after some possible re-enable
1297 // assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
1298
1299 //stop/remove(?) the device entry
Himani Chawla6d2ae152020-09-02 13:11:20 +05301300 _ = pDevEntry.stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
mpagenko3af1f032020-06-10 08:53:41 +00001301
1302 //TODO!!! remove existing traffic profiles
1303 /* from py code, if TP's exist, remove them - not yet implemented
1304 self._tp = dict()
1305 # Let TP download happen again
1306 for uni_id in self._tp_service_specific_task:
1307 self._tp_service_specific_task[uni_id].clear()
1308 for uni_id in self._tech_profile_download_done:
1309 self._tech_profile_download_done[uni_id].clear()
1310 */
1311
1312 dh.disableUniPortStateUpdate()
1313
1314 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001315 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001316 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001317 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001318 // abort: system behavior is just unstable ...
1319 return err
1320 }
1321 dh.deviceReason = "stopping-openomci"
1322
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001323 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1324 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001325 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1326 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001327 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001328 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001329 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001330 // abort: system behavior is just unstable ...
1331 return err
1332 }
1333 } else {
divyadesai4d299552020-08-18 07:13:49 +00001334 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001335 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001336 return nil
1337}
1338
Himani Chawla6d2ae152020-09-02 13:11:20 +05301339func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301340 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1341 if !dh.reconciling {
1342 //initiate DevStateUpdate
1343 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1344 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1345 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
1346 "device-id": dh.deviceID, "error": err})
1347 } else {
1348 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
1349 }
1350 } else {
1351 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1352 log.Fields{"device-id": dh.deviceID})
1353 }
1354 //set internal state anyway - as it was done
1355 dh.deviceReason = "discovery-mibsync-complete"
1356
1357 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301358 pDevEntry := dh.getOnuDeviceEntry(false)
1359 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301360 for _, mgmtEntityID := range unigInstKeys {
1361 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1362 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301363 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301364 i++
1365 }
1366 } else {
1367 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1368 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301369 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301370 for _, mgmtEntityID := range veipInstKeys {
1371 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1372 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301373 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301374 i++
1375 }
1376 } else {
1377 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1378 }
1379 if i == 0 {
1380 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1381 }
1382
1383 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1384 * left the code here as comment in case such processing should prove needed unexpectedly
1385 // Init Uni Ports to Admin locked state
1386 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1387 // *** should generate UniLockStateDone event *****
1388 if dh.pLockStateFsm == nil {
1389 dh.createUniLockFsm(true, UniLockStateDone)
1390 } else { //LockStateFSM already init
1391 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1392 dh.runUniLockFsm(true)
1393 }
1394 }
1395 case UniLockStateDone:
1396 {
1397 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1398 * lockState processing commented out
1399 */
1400 /* Mib download procedure -
1401 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1402 */
1403 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1404 if pMibDlFsm != nil {
1405 if pMibDlFsm.Is(dlStDisabled) {
1406 if err := pMibDlFsm.Event(dlEvStart); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001407 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"deviceId": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301408 // maybe try a FSM reset and then again ... - TODO!!!
1409 } else {
1410 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1411 // maybe use more specific states here for the specific download steps ...
1412 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001413 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"deviceId": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301414 } else {
1415 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1416 //Begin MIB data download (running autonomously)
1417 }
1418 }
1419 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001420 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
1421 "deviceId": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301422 // maybe try a FSM reset and then again ... - TODO!!!
1423 }
1424 /***** Mib download started */
1425 } else {
1426 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1427 }
1428}
1429
Himani Chawla6d2ae152020-09-02 13:11:20 +05301430func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301431 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1432 //initiate DevStateUpdate
1433 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001434 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1435 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301436 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1437 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1438 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1439 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1440 } else {
1441 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1442 }
1443 } else {
1444 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1445 log.Fields{"device-id": dh.deviceID})
1446 }
1447 if !dh.reconciling {
1448 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1449 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1450 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
1451 log.Fields{"device-id": dh.deviceID, "error": err})
1452 } else {
1453 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
1454 }
1455 } else {
1456 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1457 log.Fields{"device-id": dh.deviceID})
1458 }
1459 //set internal state anyway - as it was done
1460 dh.deviceReason = "initial-mib-downloaded"
1461 // *** should generate UniUnlockStateDone event *****
1462 if dh.pUnlockStateFsm == nil {
1463 dh.createUniLockFsm(false, UniUnlockStateDone)
1464 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301465 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301466 dh.runUniLockFsm(false)
1467 }
1468}
1469
Himani Chawla6d2ae152020-09-02 13:11:20 +05301470func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301471 go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
1472
1473 if !dh.reconciling {
1474 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1475 raisedTs := time.Now().UnixNano()
1476 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1477 } else {
1478 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1479 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301480 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001481 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301482 }
1483}
1484
Himani Chawla6d2ae152020-09-02 13:11:20 +05301485func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301486 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1487 // attention: the device reason update is done based on ONU-UNI-Port related activity
1488 // - which may cause some inconsistency
1489 if dh.deviceReason != "tech-profile-config-download-success" {
1490 // which may be the case from some previous actvity on another UNI Port of the ONU
1491 if !dh.reconciling {
1492 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1493 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1494 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
1495 log.Fields{"device-id": dh.deviceID, "error": err})
1496 } else {
1497 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
1498 log.Fields{"device-id": dh.deviceID})
1499 }
1500 } else {
1501 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
1502 log.Fields{"device-id": dh.deviceID})
1503 }
1504 //set internal state anyway - as it was done
1505 dh.deviceReason = "tech-profile-config-download-success"
1506 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001507 if dh.reconciling {
1508 go dh.reconcileDeviceFlowConfig()
1509 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301510}
1511
Himani Chawla6d2ae152020-09-02 13:11:20 +05301512func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301513 logger.Debugw("OmciVlanFilterDone event received",
1514 log.Fields{"device-id": dh.deviceID})
1515 // attention: the device reason update is done based on ONU-UNI-Port related activity
1516 // - which may cause some inconsistency
1517 // yield self.core_proxy.device_reason_update(self.device_id, 'omci-flows-pushed')
1518
1519 if dh.deviceReason != "omci-flows-pushed" {
1520 // which may be the case from some previous actvity on another UNI Port of the ONU
1521 // or even some previous flow add activity on the same port
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001522 if !dh.reconciling {
1523 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1524 logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
1525 log.Fields{"device-id": dh.deviceID, "error": err})
1526 } else {
1527 logger.Infow("updated dev reason to ''omci-flows-pushed'",
1528 log.Fields{"device-id": dh.deviceID})
1529 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301530 } else {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001531 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Himani Chawla26e555c2020-08-31 12:30:20 +05301532 log.Fields{"device-id": dh.deviceID})
1533 }
1534 //set internal state anyway - as it was done
1535 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001536
1537 if dh.reconciling {
1538 go dh.reconcileMetrics()
1539 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301540 }
1541}
1542
Himani Chawla6d2ae152020-09-02 13:11:20 +05301543//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1544func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301545 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001546 case MibDatabaseSync:
1547 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301548 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001549 }
1550 case MibDownloadDone:
1551 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301552 dh.processMibDownloadDoneEvent(devEvent)
1553
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001554 }
1555 case UniUnlockStateDone:
1556 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301557 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001558
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001559 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001560 case OmciAniConfigDone:
1561 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301562 dh.processOmciAniConfigDoneEvent(devEvent)
1563
mpagenko3dbcdd22020-07-22 07:38:45 +00001564 }
mpagenkodff5dda2020-08-28 11:52:01 +00001565 case OmciVlanFilterDone:
1566 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301567 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001568
mpagenkodff5dda2020-08-28 11:52:01 +00001569 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001570 default:
1571 {
Himani Chawla4d908332020-08-31 12:30:20 +05301572 logger.Warnw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001573 }
1574 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001575}
1576
Himani Chawla6d2ae152020-09-02 13:11:20 +05301577func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001578 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301579 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301580 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001581 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301582 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001583 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301584 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301585 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001586 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301587 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001588 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001589 //store UniPort with the System-PortNumber key
1590 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001591 if !dh.reconciling {
1592 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301593 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001594 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1595 } //error logging already within UniPort method
1596 } else {
1597 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1598 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001599 }
1600 }
1601}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001602
mpagenko3af1f032020-06-10 08:53:41 +00001603// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301604func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001605 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301606 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001607 // with following remark:
1608 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1609 // # load on the core
1610
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001611 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001612
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001613 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001614 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301615 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001616 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301617 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001618 if !dh.reconciling {
1619 //maybe also use getter functions on uniPort - perhaps later ...
1620 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1621 } else {
1622 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1623 }
mpagenko3af1f032020-06-10 08:53:41 +00001624 }
1625 }
1626}
1627
1628// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301629func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001630 // compare enableUniPortStateUpdate() above
1631 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1632 for uniNo, uniPort := range dh.uniEntityMap {
1633 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301634 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001635 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301636 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001637 //maybe also use getter functions on uniPort - perhaps later ...
1638 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001639 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001640 }
1641}
1642
1643// ONU_Active/Inactive announcement on system KAFKA bus
1644// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301645func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001646 var de voltha.DeviceEvent
1647 eventContext := make(map[string]string)
1648 //Populating event context
1649 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301650 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001651 if err != nil || parentDevice == nil {
1652 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301653 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001654 }
1655 oltSerialNumber := parentDevice.SerialNumber
1656
1657 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1658 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1659 eventContext["serial-number"] = dh.device.SerialNumber
1660 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301661 eventContext["device_id"] = aDeviceID
1662 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001663 logger.Debugw("prepare ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301664 log.Fields{"DeviceId": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001665
1666 /* Populating device event body */
1667 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301668 de.ResourceId = aDeviceID
1669 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001670 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1671 de.Description = fmt.Sprintf("%s Event - %s - %s",
1672 cEventObjectType, cOnuActivatedEvent, "Raised")
1673 } else {
1674 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1675 de.Description = fmt.Sprintf("%s Event - %s - %s",
1676 cEventObjectType, cOnuActivatedEvent, "Cleared")
1677 }
1678 /* Send event to KAFKA */
1679 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1680 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301681 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001682 }
1683 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301684 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001685}
1686
Himani Chawla4d908332020-08-31 12:30:20 +05301687// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301688func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001689 chLSFsm := make(chan Message, 2048)
1690 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301691 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001692 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001693 sFsmName = "LockStateFSM"
1694 } else {
divyadesai4d299552020-08-18 07:13:49 +00001695 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001696 sFsmName = "UnLockStateFSM"
1697 }
mpagenko3af1f032020-06-10 08:53:41 +00001698
Himani Chawla6d2ae152020-09-02 13:11:20 +05301699 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001700 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001701 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001702 return
1703 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301704 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001705 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001706 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301707 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001708 dh.pLockStateFsm = pLSFsm
1709 } else {
1710 dh.pUnlockStateFsm = pLSFsm
1711 }
1712 dh.runUniLockFsm(aAdminState)
1713 } else {
divyadesai4d299552020-08-18 07:13:49 +00001714 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001715 }
1716}
1717
1718// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301719func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001720 /* Uni Port lock/unlock procedure -
1721 ***** should run via 'adminDone' state and generate the argument requested event *****
1722 */
1723 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301724 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001725 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1726 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1727 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001728 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301729 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001730 }
1731 } else {
1732 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1733 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1734 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001735 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301736 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001737 }
1738 }
1739 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001740 if pLSStatemachine.Is(uniStDisabled) {
1741 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001742 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1743 // maybe try a FSM reset and then again ... - TODO!!!
1744 } else {
1745 /***** LockStateFSM started */
1746 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001747 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001748 }
1749 } else {
1750 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001751 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001752 // maybe try a FSM reset and then again ... - TODO!!!
1753 }
1754 } else {
divyadesai4d299552020-08-18 07:13:49 +00001755 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001756 // maybe try a FSM reset and then again ... - TODO!!!
1757 }
1758}
1759
Himani Chawla6d2ae152020-09-02 13:11:20 +05301760//setBackend provides a DB backend for the specified path on the existing KV client
1761func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001762 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1763 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001764 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001765 kvbackend := &db.Backend{
1766 Client: dh.pOpenOnuAc.kvClient,
1767 StoreType: dh.pOpenOnuAc.KVStoreType,
1768 /* address config update acc. to [VOL-2736] */
1769 Address: addr,
1770 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1771 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001772
mpagenkoaf801632020-07-03 10:00:42 +00001773 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001774}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301775func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301776 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001777
mpagenkodff5dda2020-08-28 11:52:01 +00001778 for _, field := range flow.GetOfbFields(apFlowItem) {
1779 switch field.Type {
1780 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1781 {
1782 logger.Debugw("FlowAdd type EthType", log.Fields{"device-id": dh.deviceID,
1783 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1784 }
1785 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1786 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301787 *loIPProto = field.GetIpProto()
mpagenkodff5dda2020-08-28 11:52:01 +00001788 logger.Debugw("FlowAdd type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301789 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1790 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001791 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1792 // avoids installing invalid EVTOCD rule
1793 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1794 log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301795 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1796 return
mpagenkodff5dda2020-08-28 11:52:01 +00001797 }
1798 }
1799 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1800 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301801 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001802 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301803 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001804 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301805 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001806 }
1807 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301808 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001809 }
1810 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1811 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301812 *loAddPcp = uint8(field.GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001813 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1814 "PCP": loAddPcp})
1815 }
1816 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1817 {
1818 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1819 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1820 }
1821 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1822 {
1823 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1824 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1825 }
1826 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1827 {
1828 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1829 "IPv4-DST": field.GetIpv4Dst()})
1830 }
1831 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1832 {
1833 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1834 "IPv4-SRC": field.GetIpv4Src()})
1835 }
1836 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1837 {
1838 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1839 "Metadata": field.GetTableMetadata()})
1840 }
1841 /*
1842 default:
1843 {
1844 //all other entires ignored
1845 }
1846 */
1847 }
1848 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301849}
mpagenkodff5dda2020-08-28 11:52:01 +00001850
Himani Chawla6d2ae152020-09-02 13:11:20 +05301851func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001852 for _, action := range flow.GetActions(apFlowItem) {
1853 switch action.Type {
1854 /* not used:
1855 case of.OfpActionType_OFPAT_OUTPUT:
1856 {
1857 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1858 "Output": action.GetOutput()})
1859 }
1860 */
1861 case of.OfpActionType_OFPAT_PUSH_VLAN:
1862 {
1863 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1864 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1865 }
1866 case of.OfpActionType_OFPAT_SET_FIELD:
1867 {
1868 pActionSetField := action.GetSetField()
1869 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
1870 logger.Warnw("FlowAdd action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
1871 "OxcmClass": pActionSetField.Field.OxmClass})
1872 }
1873 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05301874 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001875 logger.Debugw("FlowAdd Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301876 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001877 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05301878 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001879 logger.Debugw("FlowAdd Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301880 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00001881 } else {
1882 logger.Warnw("FlowAdd action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
1883 "Type": pActionSetField.Field.GetOfbField().Type})
1884 }
1885 }
1886 /*
1887 default:
1888 {
1889 //all other entires ignored
1890 }
1891 */
1892 }
1893 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05301894}
1895
1896//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05301897func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05301898 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
1899 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
1900 var loAddPcp, loSetPcp uint8
1901 var loIPProto uint32
1902 /* the TechProfileId is part of the flow Metadata - compare also comment within
1903 * OLT-Adapter:openolt_flowmgr.go
1904 * Metadata 8 bytes:
1905 * Most Significant 2 Bytes = Inner VLAN
1906 * Next 2 Bytes = Tech Profile ID(TPID)
1907 * Least Significant 4 Bytes = Port ID
1908 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
1909 * subscriber related flows.
1910 */
1911
1912 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
1913 if metadata == 0 {
1914 logger.Debugw("FlowAdd invalid metadata - abort",
1915 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001916 return fmt.Errorf("flowAdd invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05301917 }
1918 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
1919 logger.Debugw("FlowAdd TechProfileId", log.Fields{"device-id": dh.deviceID, "TP-Id": loTpID})
1920
1921 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
1922 if loIPProto == 2 {
1923 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1924 // avoids installing invalid EVTOCD rule
1925 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1926 log.Fields{"device-id": dh.deviceID,
1927 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
1928 return nil
1929 }
1930 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00001931
1932 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1933 logger.Errorw("FlowAdd aborted - SetVlanId undefined, but MatchVid set", log.Fields{
1934 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
1935 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
1936 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
1937 //TODO!!: Use DeviceId within the error response to rwCore
1938 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001939 return fmt.Errorf("flowAdd Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001940 }
1941 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
1942 logger.Debugw("FlowAdd vlan-any/copy", log.Fields{"device-id": dh.deviceID})
1943 loSetVlan = loMatchVlan //both 'transparent' (copy any)
1944 } else {
1945 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
1946 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
1947 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05301948 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001949 }
1950 logger.Debugw("FlowAdd vlan-set", log.Fields{"device-id": dh.deviceID})
1951 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301952 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001953 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00001954 }
1955 return dh.createVlanFilterFsm(apUniPort,
1956 loTpID, loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
1957}
1958
Himani Chawla26e555c2020-08-31 12:30:20 +05301959// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
Himani Chawla6d2ae152020-09-02 13:11:20 +05301960func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort,
mpagenkodff5dda2020-08-28 11:52:01 +00001961 aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
1962 chVlanFilterFsm := make(chan Message, 2048)
1963
Himani Chawla6d2ae152020-09-02 13:11:20 +05301964 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00001965 if pDevEntry == nil {
1966 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301967 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001968 }
1969
1970 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
1971 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", dh.deviceID, chVlanFilterFsm,
1972 dh.pOpenOnuAc.AcceptIncrementalEvto, aMatchVlan, aSetVlan, aSetPcp)
1973 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05301974 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001975 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1976 if pVlanFilterStatemachine != nil {
1977 if pVlanFilterStatemachine.Is(vlanStDisabled) {
1978 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
1979 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301980 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001981 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301982 /***** UniVlanConfigFsm started */
1983 logger.Debugw("UniVlanConfigFsm started", log.Fields{
1984 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
1985 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00001986 } else {
1987 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
1988 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301989 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001990 }
1991 } else {
1992 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
1993 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301994 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001995 }
1996 } else {
1997 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
1998 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05301999 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002000 }
2001 return nil
2002}
2003
2004//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302005func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002006 //TODO!! verify and start pending flow configuration
2007 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2008 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302009 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002010 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2011 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2012 if pVlanFilterStatemachine != nil {
2013 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2014 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2015 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2016 } else {
2017 /***** UniVlanConfigFsm continued */
2018 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2019 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2020 "UniPort": apUniPort.portNo})
2021 }
2022 } else {
2023 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2024 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2025 }
2026 } else {
2027 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2028 "device-id": dh.deviceID})
2029 }
2030
2031 } // else: nothing to do
2032}
2033
2034//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2035// 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 +05302036func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002037 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2038 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2039 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302040 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002041}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002042
2043//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2044//available for potential reconcilement
2045
2046func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2047
2048 if dh.reconciling {
2049 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2050 return nil
2051 }
2052 logger.Debugw("Store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2053
2054 pDevEntry := dh.getOnuDeviceEntry(true)
2055 if pDevEntry == nil {
2056 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2057 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2058 }
2059 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2060
2061 pDevEntry.lockOnuKVStoreMutex()
2062 defer pDevEntry.unlockOnuKVStoreMutex()
2063
2064 // deadline context to ensure completion of background routines waited for
2065 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +05302066 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002067 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2068
2069 pDevEntry.resetKvProcessingErrorIndication()
2070 var wg sync.WaitGroup
2071 wg.Add(1) // for the 1 go routine to finish
2072
2073 go pDevEntry.updateOnuKvStore(dctx, &wg)
2074 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
2075
2076 return pDevEntry.getKvProcessingErrorIndication()
2077}
2078
2079func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup) {
2080 defer cancel() //ensure termination of context (may be pro forma)
2081 wg.Wait()
2082 logger.Debug("WaitGroup processing completed")
2083
2084}
2085
2086func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2087 var errStr string = ""
2088 for _, err := range errS {
2089 if err != nil {
2090 errStr = errStr + err.Error() + " "
2091 }
2092 }
2093 if errStr != "" {
2094 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2095 }
2096 return nil
2097}