blob: d5a49a84ab8e87263cfeec7bf48c46a6a3c13573 [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()
mpagenko900ee4b2020-10-12 11:56:34 +0000253 logger.Debugw("inter-adapter-recv-onu-ind", log.Fields{"device-id": dh.deviceID,
254 "OnuId": onuIndication.GetOnuId(),
Himani Chawla26e555c2020-08-31 12:30:20 +0530255 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
256 "SNR": onuIndication.GetSerialNumber()})
257
258 //interface related functions might be error checked ....
259 if onuOperstate == "up" {
260 _ = dh.createInterface(onuIndication)
261 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
262 _ = dh.updateInterface(onuIndication)
263 } else {
264 logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000265 return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530266 }
267 return nil
268}
269
Himani Chawla6d2ae152020-09-02 13:11:20 +0530270func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530271 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000272
273 pDevEntry := dh.getOnuDeviceEntry(true)
274 if pDevEntry == nil {
275 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
276 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
277 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530278 if dh.pOnuTP == nil {
279 //should normally not happen ...
280 logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
281 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000282 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530283 }
284 if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock") {
285 // I've seen cases for this request, where the device was already stopped
286 logger.Warnw("TechProf stopped: device-unreachable", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000287 return fmt.Errorf("device-unreachable: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530288 }
289
290 msgBody := msg.GetBody()
291 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
292 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
293 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
294 "device-id": dh.deviceID, "error": err})
295 return err
296 }
297
298 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000299 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
300 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530301 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000302 defer dh.pOnuTP.unlockTpProcMutex()
303 pDevEntry.lockOnuKVStoreMutex()
304 defer pDevEntry.unlockOnuKVStoreMutex()
305
306 if techProfMsg.UniId > 255 {
307 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
308 techProfMsg.UniId, dh.deviceID))
309 }
310 uniID := uint8(techProfMsg.UniId)
311
312 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530313 // if there has been some change for some uni TechProfilePath
314 //in order to allow concurrent calls to other dh instances we do not wait for execution here
315 //but doing so we can not indicate problems to the caller (who does what with that then?)
316 //by now we just assume straightforward successful execution
317 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
318 // possible problems to the caller later autonomously
319
320 // deadline context to ensure completion of background routines waited for
321 //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 +0530322 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530323 dctx, cancel := context.WithDeadline(context.Background(), deadline)
324
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000325 dh.pOnuTP.resetTpProcessingErrorIndication()
326 pDevEntry.resetKvProcessingErrorIndication()
327
Himani Chawla26e555c2020-08-31 12:30:20 +0530328 var wg sync.WaitGroup
329 wg.Add(2) // for the 2 go routines to finish
330 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000331 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
332 go pDevEntry.updateOnuKvStore(dctx, &wg)
333 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
334
335 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000337 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530338 return nil
339}
340
Himani Chawla6d2ae152020-09-02 13:11:20 +0530341func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 msg *ic.InterAdapterMessage) error {
343
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000344 pDevEntry := dh.getOnuDeviceEntry(true)
345 if pDevEntry == nil {
346 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
347 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
348 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 if dh.pOnuTP == nil {
350 //should normally not happen ...
351 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
352 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000353 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 }
355
356 msgBody := msg.GetBody()
357 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
358 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
359 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
360 "device-id": dh.deviceID, "error": err})
361 return err
362 }
363
364 //compare TECH_PROFILE_DOWNLOAD_REQUEST
365 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 defer dh.pOnuTP.unlockTpProcMutex()
367 pDevEntry.lockOnuKVStoreMutex()
368 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530369
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370 if delGemPortMsg.UniId > 255 {
371 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
372 delGemPortMsg.UniId, dh.deviceID))
373 }
374 uniID := uint8(delGemPortMsg.UniId)
Himani Chawla26e555c2020-08-31 12:30:20 +0530375
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
377 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530378 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 dctx, cancel := context.WithDeadline(context.Background(), deadline)
380
381 dh.pOnuTP.resetTpProcessingErrorIndication()
382 pDevEntry.resetKvProcessingErrorIndication()
383
384 var wg sync.WaitGroup
385 wg.Add(2) // for the 2 go routines to finish
386 go pDevEntry.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
387 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
388 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
389 go pDevEntry.updateOnuKvStore(dctx, &wg)
390 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
391
392 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
393 }
394 return nil
Himani Chawla26e555c2020-08-31 12:30:20 +0530395}
396
Himani Chawla6d2ae152020-09-02 13:11:20 +0530397func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399
400 pDevEntry := dh.getOnuDeviceEntry(true)
401 if pDevEntry == nil {
402 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
403 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
404 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 if dh.pOnuTP == nil {
406 //should normally not happen ...
407 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
408 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 }
411
412 msgBody := msg.GetBody()
413 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
414 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
415 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
416 "device-id": dh.deviceID, "error": err})
417 return err
418 }
419
420 //compare TECH_PROFILE_DOWNLOAD_REQUEST
421 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000422 defer dh.pOnuTP.unlockTpProcMutex()
423 pDevEntry.lockOnuKVStoreMutex()
424 defer pDevEntry.unlockOnuKVStoreMutex()
425
426 if delTcontMsg.UniId > 255 {
427 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
428 delTcontMsg.UniId, dh.deviceID))
429 }
430 uniID := uint8(delTcontMsg.UniId)
431
432 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530433 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530434 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 dctx, cancel := context.WithDeadline(context.Background(), deadline)
436
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000437 dh.pOnuTP.resetTpProcessingErrorIndication()
438 pDevEntry.resetKvProcessingErrorIndication()
439
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 var wg sync.WaitGroup
441 wg.Add(2) // for the 2 go routines to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442 go pDevEntry.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530443 cResourceTcont, delTcontMsg.AllocId, &wg)
444 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 go pDevEntry.updateOnuKvStore(dctx, &wg)
446 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
447
448 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530450 return nil
451}
452
Himani Chawla6d2ae152020-09-02 13:11:20 +0530453//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000454// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
455// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530456func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000457 msgID := msg.Header.Id
458 msgType := msg.Header.Type
459 fromTopic := msg.Header.FromTopic
460 toTopic := msg.Header.ToTopic
461 toDeviceID := msg.Header.ToDeviceId
462 proxyDeviceID := msg.Header.ProxyDeviceId
463 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
464 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
465
466 switch msgType {
467 case ic.InterAdapterMessageType_OMCI_REQUEST:
468 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000470 }
471 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
472 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000474 }
mpagenkoaf801632020-07-03 10:00:42 +0000475 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
476 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000478 }
479 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
480 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000482
mpagenkoaf801632020-07-03 10:00:42 +0000483 }
484 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
485 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000487 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000488 default:
489 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000490 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491 "msgType": msg.Header.Type, "device-id": dh.deviceID})
492 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000493 }
494 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000495}
496
mpagenkodff5dda2020-08-28 11:52:01 +0000497//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530498func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000499 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000500 logger.Debugw("FlowUpdateIncremental started", log.Fields{"deviceId": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000501
502 //Remove flows
503 if apOfFlowChanges.ToRemove != nil {
504 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
505 logger.Debugw("incremental flow item remove", log.Fields{"deviceId": dh.deviceID,
506 "Item": flowItem})
507 }
508 }
509 if apOfFlowChanges.ToAdd != nil {
510 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
511 if flowItem.GetCookie() == 0 {
512 logger.Debugw("incremental flow add - no cookie - ignore", log.Fields{
513 "deviceId": dh.deviceID})
514 continue
515 }
516 flowInPort := flow.GetInPort(flowItem)
517 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
518 logger.Errorw("flow inPort invalid", log.Fields{"deviceID": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519 return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000520 } else if flowInPort == dh.ponPortNumber {
521 //this is some downstream flow
522 logger.Debugw("incremental flow ignore downstream", log.Fields{
523 "deviceId": dh.deviceID, "inPort": flowInPort})
524 continue
525 } else {
526 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530527 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000528 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
529 loUniPort = uniPort
530 } else {
531 logger.Errorw("flow inPort not found in UniPorts",
532 log.Fields{"deviceID": dh.deviceID, "inPort": flowInPort})
533 return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
534 }
535 flowOutPort := flow.GetOutPort(flowItem)
536 logger.Debugw("incremental flow-add port indications", log.Fields{
537 "deviceId": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
538 "uniPortName": loUniPort.name})
539 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
540 //abort processing in error case
541 if err != nil {
542 return err
543 }
544 }
545 }
546 }
547 return nil
548}
549
Himani Chawla6d2ae152020-09-02 13:11:20 +0530550//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530551func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000552 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000553
mpagenko900ee4b2020-10-12 11:56:34 +0000554 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
555 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
mpagenko3af1f032020-06-10 08:53:41 +0000556 if dh.deviceReason != "omci-admin-lock" {
mpagenko900ee4b2020-10-12 11:56:34 +0000557 //running FSM's are stopped/reset here to avoid indirect stucking
558 // due to blocked OMCI transmission on disabled state
559 // but with possibly aborted FSM's there might be complications as the expected state
560 // after some re-enable would then be quite undefined
561 // maybe after re-enabling some additional checks would be required to possibly enforce new
562 // (reconcile-like) config (which would require some indication from 'aborted' FSM's first)
563 // for now let's assume no running FSM is active at this time point here ... -> TODO!!!
564 if err := dh.resetFsms(); err != nil {
565 logger.Errorw("error-disableDevice at FSM stop",
566 log.Fields{"device-id": dh.deviceID, "error": err})
567 // abort: system behavior is just unstable ...
568 return
569 }
570
mpagenko3af1f032020-06-10 08:53:41 +0000571 // disable UNI ports/ONU
mpagenko900ee4b2020-10-12 11:56:34 +0000572 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
mpagenko3af1f032020-06-10 08:53:41 +0000573 if dh.pLockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000574 dh.createUniLockFsm(true, UniDisableStateDone)
mpagenko3af1f032020-06-10 08:53:41 +0000575 } else { //LockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000576 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
mpagenko3af1f032020-06-10 08:53:41 +0000577 dh.runUniLockFsm(true)
578 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300579 }
580}
581
Himani Chawla6d2ae152020-09-02 13:11:20 +0530582//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530583func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000584 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000585
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000586 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000587 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000588 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000589 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000590 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000591 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000592 dh.runUniLockFsm(false)
593 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300594}
595
Himani Chawla6d2ae152020-09-02 13:11:20 +0530596func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000597 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
598
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000599 pDevEntry := dh.getOnuDeviceEntry(true)
600 if pDevEntry == nil {
601 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
602 return
603 }
604 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000605 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
606 dh.reconciling = false
607 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000608 }
Himani Chawla4d908332020-08-31 12:30:20 +0530609 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000610 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
611 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
612 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
613 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530614 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000615}
616
Himani Chawla6d2ae152020-09-02 13:11:20 +0530617func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000618 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
619
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000620 pDevEntry := dh.getOnuDeviceEntry(true)
621 if pDevEntry == nil {
622 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
623 return
624 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000625
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000626 dh.pOnuTP.lockTpProcMutex()
627 defer dh.pOnuTP.unlockTpProcMutex()
628
629 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000630 // deadline context to ensure completion of background routines waited for
631 //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 +0530632 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000633 dctx, cancel := context.WithDeadline(context.Background(), deadline)
634
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000635 dh.pOnuTP.resetTpProcessingErrorIndication()
636
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000637 var wg sync.WaitGroup
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000638 wg.Add(1) // for the 1 go routine to finish
639 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPath, &wg)
640 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
641
642 if err := dh.pOnuTP.getTpProcessingErrorIndication(); err != nil {
643 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
644 }
645 }
646}
647
648func (dh *deviceHandler) reconcileDeviceFlowConfig() {
649 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
650
651 pDevEntry := dh.getOnuDeviceEntry(true)
652 if pDevEntry == nil {
653 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000654 return
655 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000656 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
657 var uniPort *onuUniPort
658 var exist bool
659 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
660 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
661 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "deviceID": dh.deviceID})
662 return
663 }
664 for _, flowData := range uniData.PersFlowParams {
665 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
666 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.TpID, uint16(flowData.MatchVid),
667 uint16(flowData.SetVid), uint8(flowData.SetPcp)); err != nil {
668 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
669 }
670
671 } else {
672 if err := dh.createVlanFilterFsm(uniPort, flowData.TpID, uint16(flowData.MatchVid), uint16(flowData.SetVid),
673 uint8(flowData.SetPcp), OmciVlanFilterDone); err != nil {
674 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
675 }
676 }
677 }
678 }
679}
680
681func (dh *deviceHandler) reconcileMetrics() {
682 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
683
684 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000685 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000686}
687
Himani Chawla6d2ae152020-09-02 13:11:20 +0530688func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000689 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000690
691 pDevEntry := dh.getOnuDeviceEntry(true)
692 if pDevEntry == nil {
693 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
694 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000695 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000696 pDevEntry.lockOnuKVStoreMutex()
697 defer pDevEntry.unlockOnuKVStoreMutex()
698
699 // deadline context to ensure completion of background routines waited for
700 //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 +0530701 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000702 dctx, cancel := context.WithDeadline(context.Background(), deadline)
703
704 pDevEntry.resetKvProcessingErrorIndication()
705
706 var wg sync.WaitGroup
707 wg.Add(1) // for the 1 go routine to finish
708 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
709 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
710
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000711 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000712 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000713}
714
Himani Chawla6d2ae152020-09-02 13:11:20 +0530715func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000716 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300717 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000718 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000719 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300720 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530721 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530722 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
723 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
724 return err
725 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200726 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000727 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200728 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300729 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000730 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000731 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300732 return err
733 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200734 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting"); 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-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300737 return err
738 }
739 dh.deviceReason = "rebooting-onu"
740 return nil
741}
742
Himani Chawla6d2ae152020-09-02 13:11:20 +0530743// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000744// #####################################################################################
745
746// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530747// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000748
Himani Chawla6d2ae152020-09-02 13:11:20 +0530749func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000750 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})
751}
752
753// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530754func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000755
756 logger.Debug("doStateInit-started")
757 var err error
758
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000759 // populate what we know. rest comes later after mib sync
760 dh.device.Root = false
761 dh.device.Vendor = "OpenONU"
762 dh.device.Model = "go"
763 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000764 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000765
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000766 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000767
768 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530769 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000770 } else {
771 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
772 log.Fields{"device-id": dh.deviceID})
773 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000774
Himani Chawla4d908332020-08-31 12:30:20 +0530775 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000776 dh.ponPortNumber = dh.device.ParentPortNo
777
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000778 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
779 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
780 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000781 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000782 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530783 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000784
785 /*
786 self._pon = PonPort.create(self, self._pon_port_number)
787 self._pon.add_peer(self.parent_id, self._pon_port_number)
788 self.logger.debug('adding-pon-port-to-agent',
789 type=self._pon.get_port().type,
790 admin_state=self._pon.get_port().admin_state,
791 oper_status=self._pon.get_port().oper_status,
792 )
793 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000794 if !dh.reconciling {
795 logger.Debugw("adding-pon-port", log.Fields{"deviceID": dh.deviceID, "ponPortNo": dh.ponPortNumber})
796 var ponPortNo uint32 = 1
797 if dh.ponPortNumber != 0 {
798 ponPortNo = dh.ponPortNumber
799 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000800
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000801 pPonPort := &voltha.Port{
802 PortNo: ponPortNo,
803 Label: fmt.Sprintf("pon-%d", ponPortNo),
804 Type: voltha.Port_PON_ONU,
805 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530806 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000807 PortNo: ponPortNo}}, // Peer port is parent's port number
808 }
809 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
810 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
811 e.Cancel(err)
812 return
813 }
814 } else {
815 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000816 }
817 logger.Debug("doStateInit-done")
818}
819
820// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530821func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000822
823 logger.Debug("postInit-started")
824 var err error
825 /*
826 dh.Client = oop.NewOpenoltClient(dh.clientCon)
827 dh.pTransitionMap.Handle(ctx, GrpcConnected)
828 return nil
829 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530830 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
831 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000832 e.Cancel(err)
833 return
834 }
835
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000836 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530837 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000838 // reconcilement will be continued after mib download is done
839 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000840 /*
841 ############################################################################
842 # Setup Alarm handler
843 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
844 device.serial_number)
845 ############################################################################
846 # Setup PM configuration for this device
847 # Pass in ONU specific options
848 kwargs = {
849 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
850 'heartbeat': self.heartbeat,
851 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
852 }
853 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
854 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
855 self.logical_device_id, device.serial_number,
856 grouped=True, freq_override=False, **kwargs)
857 pm_config = self._pm_metrics.make_proto()
858 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
859 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
860 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
861
862 # Note, ONU ID and UNI intf set in add_uni_port method
863 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
864 ani_ports=[self._pon])
865
866 # Code to Run OMCI Test Action
867 kwargs_omci_test_action = {
868 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
869 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
870 }
871 serial_number = device.serial_number
872 self._test_request = OmciTestRequest(self.core_proxy,
873 self.omci_agent, self.device_id,
874 AniG, serial_number,
875 self.logical_device_id,
876 exclusive=False,
877 **kwargs_omci_test_action)
878
879 self.enabled = True
880 else:
881 self.logger.info('onu-already-activated')
882 */
883 logger.Debug("postInit-done")
884}
885
886// doStateConnected get the device info and update to voltha core
887// for comparison of the original method (not that easy to uncomment): compare here:
888// voltha-openolt-adapter/adaptercore/device_handler.go
889// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530890func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000891
892 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530893 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000894 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000895 logger.Debug("doStateConnected-done")
896}
897
898// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530899func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000900
901 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530902 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000903 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000904 logger.Debug("doStateUp-done")
905
906 /*
907 // Synchronous call to update device state - this method is run in its own go routine
908 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
909 voltha.OperStatus_ACTIVE); err != nil {
910 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
911 return err
912 }
913 return nil
914 */
915}
916
917// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +0530918func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000919
920 logger.Debug("doStateDown-started")
921 var err error
922
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000923 device := dh.device
924 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000925 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +0200926 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000927 e.Cancel(err)
928 return
929 }
930
931 cloned := proto.Clone(device).(*voltha.Device)
932 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
933 /*
934 // Update the all ports state on that device to disable
935 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
936 logger.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
937 return er
938 }
939
940 //Update the device oper state and connection status
941 cloned.OperStatus = voltha.OperStatus_UNKNOWN
942 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
943 dh.device = cloned
944
945 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
946 logger.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
947 return er
948 }
949
950 //get the child device for the parent device
951 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
952 if err != nil {
953 logger.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
954 return err
955 }
956 for _, onuDevice := range onuDevices.Items {
957
958 // Update onu state as down in onu adapter
959 onuInd := oop.OnuIndication{}
960 onuInd.OperState = "down"
961 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
962 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
963 if er != nil {
964 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
965 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
966 //Do not return here and continue to process other ONUs
967 }
968 }
969 // * Discovered ONUs entries need to be cleared , since after OLT
970 // is up, it starts sending discovery indications again* /
971 dh.discOnus = sync.Map{}
972 logger.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
973 return nil
974 */
Himani Chawla4d908332020-08-31 12:30:20 +0530975 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000976 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000977 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000978}
979
Himani Chawla6d2ae152020-09-02 13:11:20 +0530980// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981// #################################################################################
982
983// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530984// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000985
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000986//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +0530987func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +0000988 dh.lockDevice.RLock()
989 pOnuDeviceEntry := dh.pOnuOmciDevice
990 if aWait && pOnuDeviceEntry == nil {
991 //keep the read sema short to allow for subsequent write
992 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +0000993 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000994 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
995 // so it might be needed to wait here for that event with some timeout
996 select {
997 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +0000998 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000999 return nil
1000 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001001 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001002 // if written now, we can return the written value without sema
1003 return dh.pOnuOmciDevice
1004 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001005 }
mpagenko3af1f032020-06-10 08:53:41 +00001006 dh.lockDevice.RUnlock()
1007 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001008}
1009
Himani Chawla6d2ae152020-09-02 13:11:20 +05301010//setOnuDeviceEntry sets the ONU device entry within the handler
1011func (dh *deviceHandler) setOnuDeviceEntry(
1012 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001013 dh.lockDevice.Lock()
1014 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001015 dh.pOnuOmciDevice = apDeviceEntry
1016 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001017}
1018
Himani Chawla6d2ae152020-09-02 13:11:20 +05301019//addOnuDeviceEntry creates a new ONU device or returns the existing
1020func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001021 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001022
Himani Chawla6d2ae152020-09-02 13:11:20 +05301023 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001024 if deviceEntry == nil {
1025 /* costum_me_map in python code seems always to be None,
1026 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1027 /* also no 'clock' argument - usage open ...*/
1028 /* and no alarm_db yet (oo.alarm_db) */
Himani Chawla6d2ae152020-09-02 13:11:20 +05301029 deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
mpagenkoaf801632020-07-03 10:00:42 +00001030 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001031 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001032 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
Himani Chawla6d2ae152020-09-02 13:11:20 +05301033 onuTechProfProc := newOnuUniTechProf(ctx, dh.deviceID, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001034 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301035 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001036 // fire deviceEntry ready event to spread to possibly waiting processing
1037 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001038 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001039 } else {
divyadesai4d299552020-08-18 07:13:49 +00001040 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001041 }
1042 // might be updated with some error handling !!!
1043 return nil
1044}
1045
1046// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301047func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001048 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1049 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1050
1051 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001052
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001053 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001054 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1055 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001056 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1057 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1058 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1059 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1060 }
1061 } else {
1062 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1063 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001064 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001065 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1066 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1067 // 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 +00001068 // 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 +00001069 // so let's just try to keep it simple ...
1070 /*
1071 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1072 if err != nil || device == nil {
1073 //TODO: needs to handle error scenarios
1074 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1075 return errors.New("Voltha Device not found")
1076 }
1077 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001078
Himani Chawla6d2ae152020-09-02 13:11:20 +05301079 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001080 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301081 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301082 return err
1083 }
mpagenko3af1f032020-06-10 08:53:41 +00001084 } else {
divyadesai4d299552020-08-18 07:13:49 +00001085 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001086 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001087 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001088 if !dh.reconciling {
1089 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1090 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1091 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1092 }
1093 } else {
1094 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1095 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001096 }
mpagenko3af1f032020-06-10 08:53:41 +00001097 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001098
1099 /* this might be a good time for Omci Verify message? */
1100 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301101 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001102 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001103 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301104 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001105
1106 /* give the handler some time here to wait for the OMCi verification result
1107 after Timeout start and try MibUpload FSM anyway
1108 (to prevent stopping on just not supported OMCI verification from ONU) */
1109 select {
1110 case <-time.After(2 * time.Second):
1111 logger.Warn("omci start-verification timed out (continue normal)")
1112 case testresult := <-verifyExec:
1113 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1114 }
1115
1116 /* In py code it looks earlier (on activate ..)
1117 # Code to Run OMCI Test Action
1118 kwargs_omci_test_action = {
1119 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1120 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1121 }
1122 serial_number = device.serial_number
1123 self._test_request = OmciTestRequest(self.core_proxy,
1124 self.omci_agent, self.device_id,
1125 AniG, serial_number,
1126 self.logical_device_id,
1127 exclusive=False,
1128 **kwargs_omci_test_action)
1129 ...
1130 # Start test requests after a brief pause
1131 if not self._test_request_started:
1132 self._test_request_started = True
1133 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1134 reactor.callLater(tststart, self._test_request.start_collector)
1135
1136 */
1137 /* which is then: in omci_test_request.py : */
1138 /*
1139 def start_collector(self, callback=None):
1140 """
1141 Start the collection loop for an adapter if the frequency > 0
1142
1143 :param callback: (callable) Function to call to collect PM data
1144 """
1145 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1146 if callback is None:
1147 callback = self.perform_test_omci
1148
1149 if self.lc is None:
1150 self.lc = LoopingCall(callback)
1151
1152 if self.default_freq > 0:
1153 self.lc.start(interval=self.default_freq / 10)
1154
1155 def perform_test_omci(self):
1156 """
1157 Perform the initial test request
1158 """
1159 ani_g_entities = self._device.configuration.ani_g_entities
1160 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1161 is not None else None
1162 self._entity_id = ani_g_entities_ids[0]
1163 self.logger.info('perform-test', entity_class=self._entity_class,
1164 entity_id=self._entity_id)
1165 try:
1166 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1167 result = yield self._device.omci_cc.send(frame)
1168 if not result.fields['omci_message'].fields['success_code']:
1169 self.logger.info('Self-Test Submitted Successfully',
1170 code=result.fields[
1171 'omci_message'].fields['success_code'])
1172 else:
1173 raise TestFailure('Test Failure: {}'.format(
1174 result.fields['omci_message'].fields['success_code']))
1175 except TimeoutError as e:
1176 self.deferred.errback(failure.Failure(e))
1177
1178 except Exception as e:
1179 self.logger.exception('perform-test-Error', e=e,
1180 class_id=self._entity_class,
1181 entity_id=self._entity_id)
1182 self.deferred.errback(failure.Failure(e))
1183
1184 */
1185
1186 // PM related heartbeat??? !!!TODO....
1187 //self._heartbeat.enabled = True
1188
mpagenko1cc3cb42020-07-27 15:24:38 +00001189 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1190 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1191 * 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 +05301192 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001193 */
1194 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001195 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001196 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001197 if pMibUlFsm.Is(ulStDisabled) {
1198 if err := pMibUlFsm.Event(ulEvStart); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001199 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"deviceId": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001200 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301201 }
1202 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1203 //Determine ONU status and start/re-start MIB Synchronization tasks
1204 //Determine if this ONU has ever synchronized
1205 if true { //TODO: insert valid check
1206 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001207 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"deviceId": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001208 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001209 }
Himani Chawla4d908332020-08-31 12:30:20 +05301210 } else {
1211 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001212 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"deviceId": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001213 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301214 }
1215 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1216 //Examine the MIB Data Sync
1217 // callbacks to be handled:
1218 // Event(ulEvSuccess)
1219 // Event(ulEvTimeout)
1220 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001221 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001222 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001223 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
1224 "deviceId": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001225 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001226 }
1227 } else {
divyadesai4d299552020-08-18 07:13:49 +00001228 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001229 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001230 }
1231 return nil
1232}
1233
Himani Chawla6d2ae152020-09-02 13:11:20 +05301234func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001235 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1236 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001237 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001238 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1239 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1240 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1241 if err := dh.resetFsms(); err != nil {
1242 logger.Errorw("error-updateInterface at FSM stop",
1243 log.Fields{"device-id": dh.deviceID, "error": err})
1244 // abort: system behavior is just unstable ...
1245 return err
1246 }
1247
1248 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1249 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1250 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301251 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001252 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001253 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001254 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001255 }
mpagenko900ee4b2020-10-12 11:56:34 +00001256 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001257
1258 //TODO!!! remove existing traffic profiles
1259 /* from py code, if TP's exist, remove them - not yet implemented
1260 self._tp = dict()
1261 # Let TP download happen again
1262 for uni_id in self._tp_service_specific_task:
1263 self._tp_service_specific_task[uni_id].clear()
1264 for uni_id in self._tech_profile_download_done:
1265 self._tech_profile_download_done[uni_id].clear()
1266 */
1267
1268 dh.disableUniPortStateUpdate()
1269
1270 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001271 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001272 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001273 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001274 // abort: system behavior is just unstable ...
1275 return err
1276 }
1277 dh.deviceReason = "stopping-openomci"
1278
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001279 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1280 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001281 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1282 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001283 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001284 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001285 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001286 // abort: system behavior is just unstable ...
1287 return err
1288 }
1289 } else {
divyadesai4d299552020-08-18 07:13:49 +00001290 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001291 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001292 return nil
1293}
1294
mpagenko900ee4b2020-10-12 11:56:34 +00001295func (dh *deviceHandler) resetFsms() error {
1296 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1297 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1298 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1299 // and using the stop/reset event should never harm
1300
1301 pDevEntry := dh.getOnuDeviceEntry(false)
1302 if pDevEntry == nil {
1303 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1304 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1305 }
1306
1307 //the MibSync FSM might be active all the ONU-active time,
1308 // hence it must be stopped unconditionally
1309 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1310 if pMibUlFsm != nil {
1311 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1312 }
1313 //MibDownload may run
1314 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1315 if pMibDlFsm != nil {
1316 _ = pMibDlFsm.Event(dlEvReset)
1317 }
1318 //port lock/unlock FSM's may be active
1319 if dh.pUnlockStateFsm != nil {
1320 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1321 }
1322 if dh.pLockStateFsm != nil {
1323 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1324 }
1325 //techProfile related PonAniConfigFsm FSM may be active
1326 if dh.pOnuTP != nil {
1327 // should always be the case here
1328 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1329 if dh.pOnuTP.pAniConfigFsm != nil {
1330 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1331 }
1332 for _, uniPort := range dh.uniEntityMap {
1333 //reset the TechProfileConfig Done state for all (active) UNI's
1334 dh.pOnuTP.setConfigDone(uniPort.uniID, false)
1335 // reset the possibly existing VlanConfigFsm
1336 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1337 //VlanFilterFsm exists and was already started
1338 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1339 if pVlanFilterStatemachine != nil {
1340 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1341 }
1342 }
1343 }
1344 }
1345 //TODO!!! care about PM/Alarm processing once started
1346 return nil
1347}
1348
Himani Chawla6d2ae152020-09-02 13:11:20 +05301349func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301350 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1351 if !dh.reconciling {
1352 //initiate DevStateUpdate
1353 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1354 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1355 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
1356 "device-id": dh.deviceID, "error": err})
1357 } else {
1358 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
1359 }
1360 } else {
1361 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1362 log.Fields{"device-id": dh.deviceID})
1363 }
1364 //set internal state anyway - as it was done
1365 dh.deviceReason = "discovery-mibsync-complete"
1366
1367 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301368 pDevEntry := dh.getOnuDeviceEntry(false)
1369 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301370 for _, mgmtEntityID := range unigInstKeys {
1371 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1372 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301373 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301374 i++
1375 }
1376 } else {
1377 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1378 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301379 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301380 for _, mgmtEntityID := range veipInstKeys {
1381 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1382 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301383 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301384 i++
1385 }
1386 } else {
1387 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1388 }
1389 if i == 0 {
1390 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1391 }
1392
1393 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1394 * left the code here as comment in case such processing should prove needed unexpectedly
1395 // Init Uni Ports to Admin locked state
1396 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1397 // *** should generate UniLockStateDone event *****
1398 if dh.pLockStateFsm == nil {
1399 dh.createUniLockFsm(true, UniLockStateDone)
1400 } else { //LockStateFSM already init
1401 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1402 dh.runUniLockFsm(true)
1403 }
1404 }
1405 case UniLockStateDone:
1406 {
1407 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1408 * lockState processing commented out
1409 */
1410 /* Mib download procedure -
1411 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1412 */
1413 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1414 if pMibDlFsm != nil {
1415 if pMibDlFsm.Is(dlStDisabled) {
1416 if err := pMibDlFsm.Event(dlEvStart); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001417 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"deviceId": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301418 // maybe try a FSM reset and then again ... - TODO!!!
1419 } else {
1420 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1421 // maybe use more specific states here for the specific download steps ...
1422 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
Andrea Campanella6515c582020-10-05 11:25:00 +02001423 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"deviceId": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301424 } else {
1425 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1426 //Begin MIB data download (running autonomously)
1427 }
1428 }
1429 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001430 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
1431 "deviceId": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301432 // maybe try a FSM reset and then again ... - TODO!!!
1433 }
1434 /***** Mib download started */
1435 } else {
1436 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1437 }
1438}
1439
Himani Chawla6d2ae152020-09-02 13:11:20 +05301440func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301441 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1442 //initiate DevStateUpdate
1443 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001444 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1445 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301446 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1447 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1448 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1449 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1450 } else {
1451 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1452 }
1453 } else {
1454 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1455 log.Fields{"device-id": dh.deviceID})
1456 }
1457 if !dh.reconciling {
1458 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1459 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1460 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
1461 log.Fields{"device-id": dh.deviceID, "error": err})
1462 } else {
1463 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
1464 }
1465 } else {
1466 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1467 log.Fields{"device-id": dh.deviceID})
1468 }
1469 //set internal state anyway - as it was done
1470 dh.deviceReason = "initial-mib-downloaded"
1471 // *** should generate UniUnlockStateDone event *****
1472 if dh.pUnlockStateFsm == nil {
1473 dh.createUniLockFsm(false, UniUnlockStateDone)
1474 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301475 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301476 dh.runUniLockFsm(false)
1477 }
1478}
1479
Himani Chawla6d2ae152020-09-02 13:11:20 +05301480func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001481 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301482
1483 if !dh.reconciling {
1484 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1485 raisedTs := time.Now().UnixNano()
1486 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1487 } else {
1488 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1489 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301490 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001491 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301492 }
1493}
1494
mpagenko900ee4b2020-10-12 11:56:34 +00001495func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1496 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1497 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1498 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1499 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1500 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1501 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1502 }
1503
1504 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1505 "reason": "omci-admin-lock", "device-id": dh.deviceID})
1506 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1507 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
1508 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1509 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1510 }
1511 dh.deviceReason = "omci-admin-lock"
1512
1513 //transfer the modified logical uni port state
1514 dh.disableUniPortStateUpdate()
1515
1516 //stop the device entry which resets the attached omciCC
1517 pDevEntry := dh.getOnuDeviceEntry(false)
1518 if pDevEntry == nil {
1519 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1520 return
1521 }
1522 _ = pDevEntry.stop(context.TODO(), true) //stop deviceEntry with omciCC reset
1523 //maybe some more sophisticated context treatment should be used here?
1524}
1525
1526func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1527 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1528 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1529 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1530 voltha.OperStatus_ACTIVE); err != nil {
1531 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1532 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1533 }
1534
1535 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1536 "reason": "onu-reenabled", "device-id": dh.deviceID})
1537 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1538 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
1539 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1540 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1541 }
1542 dh.deviceReason = "onu-reenabled"
1543
1544 //transfer the modified logical uni port state
1545 dh.enableUniPortStateUpdate()
1546}
1547
Himani Chawla6d2ae152020-09-02 13:11:20 +05301548func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301549 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1550 // attention: the device reason update is done based on ONU-UNI-Port related activity
1551 // - which may cause some inconsistency
1552 if dh.deviceReason != "tech-profile-config-download-success" {
1553 // which may be the case from some previous actvity on another UNI Port of the ONU
1554 if !dh.reconciling {
1555 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1556 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1557 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
1558 log.Fields{"device-id": dh.deviceID, "error": err})
1559 } else {
1560 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
1561 log.Fields{"device-id": dh.deviceID})
1562 }
1563 } else {
1564 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
1565 log.Fields{"device-id": dh.deviceID})
1566 }
1567 //set internal state anyway - as it was done
1568 dh.deviceReason = "tech-profile-config-download-success"
1569 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001570 if dh.reconciling {
1571 go dh.reconcileDeviceFlowConfig()
1572 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301573}
1574
Himani Chawla6d2ae152020-09-02 13:11:20 +05301575func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301576 logger.Debugw("OmciVlanFilterDone event received",
1577 log.Fields{"device-id": dh.deviceID})
1578 // attention: the device reason update is done based on ONU-UNI-Port related activity
1579 // - which may cause some inconsistency
1580 // yield self.core_proxy.device_reason_update(self.device_id, 'omci-flows-pushed')
1581
1582 if dh.deviceReason != "omci-flows-pushed" {
1583 // which may be the case from some previous actvity on another UNI Port of the ONU
1584 // or even some previous flow add activity on the same port
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001585 if !dh.reconciling {
1586 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1587 logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
1588 log.Fields{"device-id": dh.deviceID, "error": err})
1589 } else {
1590 logger.Infow("updated dev reason to ''omci-flows-pushed'",
1591 log.Fields{"device-id": dh.deviceID})
1592 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301593 } else {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001594 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Himani Chawla26e555c2020-08-31 12:30:20 +05301595 log.Fields{"device-id": dh.deviceID})
1596 }
1597 //set internal state anyway - as it was done
1598 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001599
1600 if dh.reconciling {
1601 go dh.reconcileMetrics()
1602 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301603 }
1604}
1605
Himani Chawla6d2ae152020-09-02 13:11:20 +05301606//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1607func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301608 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001609 case MibDatabaseSync:
1610 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301611 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001612 }
1613 case MibDownloadDone:
1614 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301615 dh.processMibDownloadDoneEvent(devEvent)
1616
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001617 }
1618 case UniUnlockStateDone:
1619 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301620 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001621
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001622 }
mpagenko900ee4b2020-10-12 11:56:34 +00001623 case UniEnableStateDone:
1624 {
1625 dh.processUniEnableStateDoneEvent(devEvent)
1626
1627 }
1628 case UniDisableStateDone:
1629 {
1630 dh.processUniDisableStateDoneEvent(devEvent)
1631
1632 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001633 case OmciAniConfigDone:
1634 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301635 dh.processOmciAniConfigDoneEvent(devEvent)
1636
mpagenko3dbcdd22020-07-22 07:38:45 +00001637 }
mpagenkodff5dda2020-08-28 11:52:01 +00001638 case OmciVlanFilterDone:
1639 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301640 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001641
mpagenkodff5dda2020-08-28 11:52:01 +00001642 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001643 default:
1644 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001645 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001646 }
1647 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648}
1649
Himani Chawla6d2ae152020-09-02 13:11:20 +05301650func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001651 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301652 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301653 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001654 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301655 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301657 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301658 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301660 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001662 //store UniPort with the System-PortNumber key
1663 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001664 if !dh.reconciling {
1665 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301666 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001667 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1668 } //error logging already within UniPort method
1669 } else {
1670 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1671 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001672 }
1673 }
1674}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001675
mpagenko3af1f032020-06-10 08:53:41 +00001676// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301677func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001678 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301679 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001680 // with following remark:
1681 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1682 // # load on the core
1683
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001684 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001685
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001686 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001687 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301688 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001689 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301690 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001691 if !dh.reconciling {
1692 //maybe also use getter functions on uniPort - perhaps later ...
1693 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1694 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001695 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001696 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1697 }
mpagenko3af1f032020-06-10 08:53:41 +00001698 }
1699 }
1700}
1701
1702// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301703func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001704 // compare enableUniPortStateUpdate() above
1705 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1706 for uniNo, uniPort := range dh.uniEntityMap {
1707 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301708 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001709 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301710 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001711 //maybe also use getter functions on uniPort - perhaps later ...
1712 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001713 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001714 }
1715}
1716
1717// ONU_Active/Inactive announcement on system KAFKA bus
1718// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301719func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001720 var de voltha.DeviceEvent
1721 eventContext := make(map[string]string)
1722 //Populating event context
1723 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301724 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001725 if err != nil || parentDevice == nil {
1726 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301727 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001728 }
1729 oltSerialNumber := parentDevice.SerialNumber
1730
1731 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1732 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1733 eventContext["serial-number"] = dh.device.SerialNumber
1734 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301735 eventContext["device_id"] = aDeviceID
1736 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001737 logger.Debugw("prepare ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301738 log.Fields{"DeviceId": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001739
1740 /* Populating device event body */
1741 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301742 de.ResourceId = aDeviceID
1743 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001744 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1745 de.Description = fmt.Sprintf("%s Event - %s - %s",
1746 cEventObjectType, cOnuActivatedEvent, "Raised")
1747 } else {
1748 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1749 de.Description = fmt.Sprintf("%s Event - %s - %s",
1750 cEventObjectType, cOnuActivatedEvent, "Cleared")
1751 }
1752 /* Send event to KAFKA */
1753 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1754 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301755 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001756 }
1757 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301758 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001759}
1760
Himani Chawla4d908332020-08-31 12:30:20 +05301761// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301762func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001763 chLSFsm := make(chan Message, 2048)
1764 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301765 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001766 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001767 sFsmName = "LockStateFSM"
1768 } else {
divyadesai4d299552020-08-18 07:13:49 +00001769 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001770 sFsmName = "UnLockStateFSM"
1771 }
mpagenko3af1f032020-06-10 08:53:41 +00001772
Himani Chawla6d2ae152020-09-02 13:11:20 +05301773 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001774 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001775 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001776 return
1777 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301778 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001779 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001780 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301781 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001782 dh.pLockStateFsm = pLSFsm
1783 } else {
1784 dh.pUnlockStateFsm = pLSFsm
1785 }
1786 dh.runUniLockFsm(aAdminState)
1787 } else {
divyadesai4d299552020-08-18 07:13:49 +00001788 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001789 }
1790}
1791
1792// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301793func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001794 /* Uni Port lock/unlock procedure -
1795 ***** should run via 'adminDone' state and generate the argument requested event *****
1796 */
1797 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301798 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001799 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1800 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1801 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001802 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301803 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001804 }
1805 } else {
1806 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1807 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1808 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001809 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301810 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001811 }
1812 }
1813 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001814 if pLSStatemachine.Is(uniStDisabled) {
1815 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001816 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1817 // maybe try a FSM reset and then again ... - TODO!!!
1818 } else {
1819 /***** LockStateFSM started */
1820 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001821 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001822 }
1823 } else {
1824 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001825 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001826 // maybe try a FSM reset and then again ... - TODO!!!
1827 }
1828 } else {
divyadesai4d299552020-08-18 07:13:49 +00001829 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001830 // maybe try a FSM reset and then again ... - TODO!!!
1831 }
1832}
1833
Himani Chawla6d2ae152020-09-02 13:11:20 +05301834//setBackend provides a DB backend for the specified path on the existing KV client
1835func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001836 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1837 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001838 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001839 kvbackend := &db.Backend{
1840 Client: dh.pOpenOnuAc.kvClient,
1841 StoreType: dh.pOpenOnuAc.KVStoreType,
1842 /* address config update acc. to [VOL-2736] */
1843 Address: addr,
1844 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1845 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001846
mpagenkoaf801632020-07-03 10:00:42 +00001847 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001848}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301849func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301850 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001851
mpagenkodff5dda2020-08-28 11:52:01 +00001852 for _, field := range flow.GetOfbFields(apFlowItem) {
1853 switch field.Type {
1854 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1855 {
1856 logger.Debugw("FlowAdd type EthType", log.Fields{"device-id": dh.deviceID,
1857 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1858 }
1859 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1860 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301861 *loIPProto = field.GetIpProto()
mpagenkodff5dda2020-08-28 11:52:01 +00001862 logger.Debugw("FlowAdd type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301863 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1864 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001865 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1866 // avoids installing invalid EVTOCD rule
1867 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
1868 log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301869 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1870 return
mpagenkodff5dda2020-08-28 11:52:01 +00001871 }
1872 }
1873 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1874 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301875 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001876 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301877 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001878 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301879 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001880 }
1881 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301882 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001883 }
1884 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1885 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301886 *loAddPcp = uint8(field.GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001887 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1888 "PCP": loAddPcp})
1889 }
1890 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1891 {
1892 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1893 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1894 }
1895 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1896 {
1897 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1898 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1899 }
1900 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1901 {
1902 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1903 "IPv4-DST": field.GetIpv4Dst()})
1904 }
1905 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1906 {
1907 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1908 "IPv4-SRC": field.GetIpv4Src()})
1909 }
1910 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
1911 {
1912 logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
1913 "Metadata": field.GetTableMetadata()})
1914 }
1915 /*
1916 default:
1917 {
1918 //all other entires ignored
1919 }
1920 */
1921 }
1922 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05301923}
mpagenkodff5dda2020-08-28 11:52:01 +00001924
Himani Chawla6d2ae152020-09-02 13:11:20 +05301925func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00001926 for _, action := range flow.GetActions(apFlowItem) {
1927 switch action.Type {
1928 /* not used:
1929 case of.OfpActionType_OFPAT_OUTPUT:
1930 {
1931 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1932 "Output": action.GetOutput()})
1933 }
1934 */
1935 case of.OfpActionType_OFPAT_PUSH_VLAN:
1936 {
1937 logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
1938 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
1939 }
1940 case of.OfpActionType_OFPAT_SET_FIELD:
1941 {
1942 pActionSetField := action.GetSetField()
1943 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
1944 logger.Warnw("FlowAdd action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
1945 "OxcmClass": pActionSetField.Field.OxmClass})
1946 }
1947 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05301948 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001949 logger.Debugw("FlowAdd Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301950 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001951 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05301952 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenkodff5dda2020-08-28 11:52:01 +00001953 logger.Debugw("FlowAdd Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301954 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00001955 } else {
1956 logger.Warnw("FlowAdd action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
1957 "Type": pActionSetField.Field.GetOfbField().Type})
1958 }
1959 }
1960 /*
1961 default:
1962 {
1963 //all other entires ignored
1964 }
1965 */
1966 }
1967 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05301968}
1969
1970//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05301971func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05301972 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
1973 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
1974 var loAddPcp, loSetPcp uint8
1975 var loIPProto uint32
1976 /* the TechProfileId is part of the flow Metadata - compare also comment within
1977 * OLT-Adapter:openolt_flowmgr.go
1978 * Metadata 8 bytes:
1979 * Most Significant 2 Bytes = Inner VLAN
1980 * Next 2 Bytes = Tech Profile ID(TPID)
1981 * Least Significant 4 Bytes = Port ID
1982 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
1983 * subscriber related flows.
1984 */
1985
1986 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
1987 if metadata == 0 {
1988 logger.Debugw("FlowAdd invalid metadata - abort",
1989 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001990 return fmt.Errorf("flowAdd invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05301991 }
1992 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
1993 logger.Debugw("FlowAdd TechProfileId", log.Fields{"device-id": dh.deviceID, "TP-Id": loTpID})
1994
1995 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
1996 if loIPProto == 2 {
1997 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1998 // avoids installing invalid EVTOCD rule
1999 logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
2000 log.Fields{"device-id": dh.deviceID,
2001 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2002 return nil
2003 }
2004 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002005
2006 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2007 logger.Errorw("FlowAdd aborted - SetVlanId undefined, but MatchVid set", log.Fields{
2008 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2009 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2010 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2011 //TODO!!: Use DeviceId within the error response to rwCore
2012 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002013 return fmt.Errorf("flowAdd Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002014 }
2015 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
2016 logger.Debugw("FlowAdd vlan-any/copy", log.Fields{"device-id": dh.deviceID})
2017 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2018 } else {
2019 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2020 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2021 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302022 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002023 }
2024 logger.Debugw("FlowAdd vlan-set", log.Fields{"device-id": dh.deviceID})
2025 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302026 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002027 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002028 }
2029 return dh.createVlanFilterFsm(apUniPort,
2030 loTpID, loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
2031}
2032
Himani Chawla26e555c2020-08-31 12:30:20 +05302033// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
Himani Chawla6d2ae152020-09-02 13:11:20 +05302034func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort,
mpagenkodff5dda2020-08-28 11:52:01 +00002035 aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
2036 chVlanFilterFsm := make(chan Message, 2048)
2037
Himani Chawla6d2ae152020-09-02 13:11:20 +05302038 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002039 if pDevEntry == nil {
2040 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302041 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002042 }
2043
2044 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
2045 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", dh.deviceID, chVlanFilterFsm,
2046 dh.pOpenOnuAc.AcceptIncrementalEvto, aMatchVlan, aSetVlan, aSetPcp)
2047 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302048 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002049 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2050 if pVlanFilterStatemachine != nil {
2051 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2052 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2053 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302054 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002055 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302056 /***** UniVlanConfigFsm started */
2057 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2058 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2059 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002060 } else {
2061 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2062 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302063 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002064 }
2065 } else {
2066 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2067 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302068 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002069 }
2070 } else {
2071 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2072 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302073 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002074 }
2075 return nil
2076}
2077
2078//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302079func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002080 //TODO!! verify and start pending flow configuration
2081 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2082 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302083 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002084 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2085 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2086 if pVlanFilterStatemachine != nil {
2087 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2088 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2089 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2090 } else {
2091 /***** UniVlanConfigFsm continued */
2092 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2093 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2094 "UniPort": apUniPort.portNo})
2095 }
2096 } else {
2097 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2098 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2099 }
2100 } else {
2101 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2102 "device-id": dh.deviceID})
2103 }
2104
2105 } // else: nothing to do
2106}
2107
2108//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2109// 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 +05302110func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002111 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2112 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2113 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302114 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002115}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002116
2117//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2118//available for potential reconcilement
2119
2120func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2121
2122 if dh.reconciling {
2123 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2124 return nil
2125 }
2126 logger.Debugw("Store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2127
2128 pDevEntry := dh.getOnuDeviceEntry(true)
2129 if pDevEntry == nil {
2130 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2131 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2132 }
2133 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2134
2135 pDevEntry.lockOnuKVStoreMutex()
2136 defer pDevEntry.unlockOnuKVStoreMutex()
2137
2138 // deadline context to ensure completion of background routines waited for
2139 //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 +05302140 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002141 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2142
2143 pDevEntry.resetKvProcessingErrorIndication()
2144 var wg sync.WaitGroup
2145 wg.Add(1) // for the 1 go routine to finish
2146
2147 go pDevEntry.updateOnuKvStore(dctx, &wg)
2148 dh.waitForCompletion(cancel, &wg) //wait for background process to finish
2149
2150 return pDevEntry.getKvProcessingErrorIndication()
2151}
2152
2153func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup) {
2154 defer cancel() //ensure termination of context (may be pro forma)
2155 wg.Wait()
2156 logger.Debug("WaitGroup processing completed")
2157
2158}
2159
2160func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2161 var errStr string = ""
2162 for _, err := range errS {
2163 if err != nil {
2164 errStr = errStr + err.Error() + " "
2165 }
2166 }
2167 if errStr != "" {
2168 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2169 }
2170 return nil
2171}