blob: 4dce9b5901375baf801f862702b460cf29a8363a [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
mpagenkofc4f56e2020-11-04 17:17:49 +0000130 stopCollector chan bool
131 stopHeartbeatCheck chan bool
132 activePorts sync.Map
133 uniEntityMap map[uint32]*onuUniPort
134 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
135 reconciling bool
136 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000137}
138
Himani Chawla6d2ae152020-09-02 13:11:20 +0530139//newDeviceHandler creates a new device handler
140func newDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
141 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000142 dh.coreProxy = cp
143 dh.AdapterProxy = ap
144 dh.EventProxy = ep
145 cloned := (proto.Clone(device)).(*voltha.Device)
146 dh.deviceID = cloned.Id
147 dh.DeviceType = cloned.Type
148 dh.adminState = "up"
149 dh.device = cloned
150 dh.pOpenOnuAc = adapter
151 dh.exitChannel = make(chan int, 1)
152 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000153 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000154 dh.stopCollector = make(chan bool, 2)
155 dh.stopHeartbeatCheck = make(chan bool, 2)
156 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
157 dh.activePorts = sync.Map{}
158 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530159 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000160 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000161 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000162 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163
164 // Device related state machine
165 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000166 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000167 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000168 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
169 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
170 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
171 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
172 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173 },
174 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000175 "before_event": func(e *fsm.Event) { dh.logStateChange(e) },
176 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(e) },
177 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(e) },
178 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(e) },
179 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
180 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(e) },
181 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(e) },
182 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183 },
184 )
mpagenkoaf801632020-07-03 10:00:42 +0000185
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186 return &dh
187}
188
Himani Chawla6d2ae152020-09-02 13:11:20 +0530189// start save the device to the data model
190func (dh *deviceHandler) start(ctx context.Context) {
divyadesai4d299552020-08-18 07:13:49 +0000191 logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000192 // Add the initial device to the local model
193 logger.Debug("device-handler-started")
194}
195
Himani Chawla4d908332020-08-31 12:30:20 +0530196/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530198func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000199 logger.Debug("stopping-device-handler")
200 dh.exitChannel <- 1
201}
Himani Chawla4d908332020-08-31 12:30:20 +0530202*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000203
204// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530205// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206
Himani Chawla6d2ae152020-09-02 13:11:20 +0530207//adoptOrReconcileDevice adopts the OLT device
208func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000209 logger.Debugw("Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000211 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000212 if dh.pDeviceStateFsm.Is(devStNull) {
213 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000214 logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
215 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000216 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000217 } else {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000218 logger.Debugw("AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219 }
220
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000221}
222
Himani Chawla6d2ae152020-09-02 13:11:20 +0530223func (dh *deviceHandler) processInterAdapterOMCIReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530224 msgBody := msg.GetBody()
225 omciMsg := &ic.InterAdapterOmciMessage{}
226 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
227 logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
228 "device-id": dh.deviceID, "error": err})
229 return err
230 }
231
232 //assuming omci message content is hex coded!
233 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
234 logger.Debugw("inter-adapter-recv-omci", log.Fields{
235 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
236 //receive_message(omci_msg.message)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530237 pDevEntry := dh.getOnuDeviceEntry(true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530238 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000239 if pDevEntry.PDevOmciCC != nil {
240 return pDevEntry.PDevOmciCC.receiveMessage(context.TODO(), omciMsg.Message)
241 }
242 logger.Debugw("omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530243 }
244 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000245 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530246}
247
Himani Chawla6d2ae152020-09-02 13:11:20 +0530248func (dh *deviceHandler) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530249 msgBody := msg.GetBody()
250 onuIndication := &oop.OnuIndication{}
251 if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
252 logger.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{
253 "device-id": dh.deviceID, "error": err})
254 return err
255 }
256
257 onuOperstate := onuIndication.GetOperState()
mpagenko900ee4b2020-10-12 11:56:34 +0000258 logger.Debugw("inter-adapter-recv-onu-ind", log.Fields{"device-id": dh.deviceID,
259 "OnuId": onuIndication.GetOnuId(),
Himani Chawla26e555c2020-08-31 12:30:20 +0530260 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
261 "SNR": onuIndication.GetSerialNumber()})
262
263 //interface related functions might be error checked ....
264 if onuOperstate == "up" {
265 _ = dh.createInterface(onuIndication)
266 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
267 _ = dh.updateInterface(onuIndication)
268 } else {
269 logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000270 return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530271 }
272 return nil
273}
274
Himani Chawla6d2ae152020-09-02 13:11:20 +0530275func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530276 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000277
278 pDevEntry := dh.getOnuDeviceEntry(true)
279 if pDevEntry == nil {
280 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
281 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
282 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530283 if dh.pOnuTP == nil {
284 //should normally not happen ...
285 logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
286 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000287 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530288 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000289 if !dh.ReadyForSpecificOmciConfig {
290 logger.Warnw("TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
291 "device-state": dh.deviceReason})
292 return fmt.Errorf("improper device state %s on device %s", dh.deviceReason, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530293 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000294 //previous state test here was just this one, now extended for more states to reject the SetRequest:
295 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
296 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530297
298 msgBody := msg.GetBody()
299 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
300 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
301 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
302 "device-id": dh.deviceID, "error": err})
303 return err
304 }
305
306 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000307 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
308 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530309 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000310 defer dh.pOnuTP.unlockTpProcMutex()
311 pDevEntry.lockOnuKVStoreMutex()
312 defer pDevEntry.unlockOnuKVStoreMutex()
313
314 if techProfMsg.UniId > 255 {
315 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
316 techProfMsg.UniId, dh.deviceID))
317 }
318 uniID := uint8(techProfMsg.UniId)
319
320 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530321 // if there has been some change for some uni TechProfilePath
322 //in order to allow concurrent calls to other dh instances we do not wait for execution here
323 //but doing so we can not indicate problems to the caller (who does what with that then?)
324 //by now we just assume straightforward successful execution
325 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
326 // possible problems to the caller later autonomously
327
328 // deadline context to ensure completion of background routines waited for
329 //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 +0530330 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530331 dctx, cancel := context.WithDeadline(context.Background(), deadline)
332
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000333 dh.pOnuTP.resetTpProcessingErrorIndication()
334 pDevEntry.resetKvProcessingErrorIndication()
335
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 var wg sync.WaitGroup
337 wg.Add(2) // for the 2 go routines to finish
338 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000339 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
340 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000341 dh.waitForCompletion(cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000342
343 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530344 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000345 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 return nil
347}
348
Himani Chawla6d2ae152020-09-02 13:11:20 +0530349func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 msg *ic.InterAdapterMessage) error {
351
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000352 pDevEntry := dh.getOnuDeviceEntry(true)
353 if pDevEntry == nil {
354 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
355 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
356 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 if dh.pOnuTP == nil {
358 //should normally not happen ...
359 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
360 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000361 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 }
363
364 msgBody := msg.GetBody()
365 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
366 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
367 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
368 "device-id": dh.deviceID, "error": err})
369 return err
370 }
371
372 //compare TECH_PROFILE_DOWNLOAD_REQUEST
373 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 defer dh.pOnuTP.unlockTpProcMutex()
375 pDevEntry.lockOnuKVStoreMutex()
376 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530377
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 if delGemPortMsg.UniId > 255 {
379 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
380 delGemPortMsg.UniId, dh.deviceID))
381 }
382 uniID := uint8(delGemPortMsg.UniId)
Himani Chawla26e555c2020-08-31 12:30:20 +0530383
mpagenkofc4f56e2020-11-04 17:17:49 +0000384 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385
mpagenkofc4f56e2020-11-04 17:17:49 +0000386 // deadline context to ensure completion of background routines waited for
387 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
388 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389
mpagenkofc4f56e2020-11-04 17:17:49 +0000390 dh.pOnuTP.resetTpProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000391
mpagenkofc4f56e2020-11-04 17:17:49 +0000392 var wg sync.WaitGroup
393 wg.Add(1) // for the 1 go routine to finish
394 go dh.pOnuTP.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
395 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
396 dh.waitForCompletion(cancel, &wg, "GemDelete") //wait for background process to finish
397
398 return dh.pOnuTP.getTpProcessingErrorIndication()
Himani Chawla26e555c2020-08-31 12:30:20 +0530399}
400
Himani Chawla6d2ae152020-09-02 13:11:20 +0530401func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530402 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403
404 pDevEntry := dh.getOnuDeviceEntry(true)
405 if pDevEntry == nil {
406 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
407 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
408 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530409 if dh.pOnuTP == nil {
410 //should normally not happen ...
411 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
412 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530414 }
415
416 msgBody := msg.GetBody()
417 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
418 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
419 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
420 "device-id": dh.deviceID, "error": err})
421 return err
422 }
423
424 //compare TECH_PROFILE_DOWNLOAD_REQUEST
425 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426 defer dh.pOnuTP.unlockTpProcMutex()
427 pDevEntry.lockOnuKVStoreMutex()
428 defer pDevEntry.unlockOnuKVStoreMutex()
429
430 if delTcontMsg.UniId > 255 {
431 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
432 delTcontMsg.UniId, dh.deviceID))
433 }
434 uniID := uint8(delTcontMsg.UniId)
435
436 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530437 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530438 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530439 dctx, cancel := context.WithDeadline(context.Background(), deadline)
440
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000441 dh.pOnuTP.resetTpProcessingErrorIndication()
442 pDevEntry.resetKvProcessingErrorIndication()
443
Himani Chawla26e555c2020-08-31 12:30:20 +0530444 var wg sync.WaitGroup
445 wg.Add(2) // for the 2 go routines to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000446 go dh.pOnuTP.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530447 cResourceTcont, delTcontMsg.AllocId, &wg)
448 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000449 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000450 dh.waitForCompletion(cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000451
452 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530454 return nil
455}
456
Himani Chawla6d2ae152020-09-02 13:11:20 +0530457//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000458// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
459// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530460func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000461 msgID := msg.Header.Id
462 msgType := msg.Header.Type
463 fromTopic := msg.Header.FromTopic
464 toTopic := msg.Header.ToTopic
465 toDeviceID := msg.Header.ToDeviceId
466 proxyDeviceID := msg.Header.ProxyDeviceId
467 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
468 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
469
470 switch msgType {
471 case ic.InterAdapterMessageType_OMCI_REQUEST:
472 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000474 }
475 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
476 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000478 }
mpagenkoaf801632020-07-03 10:00:42 +0000479 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
480 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000482 }
483 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
484 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000486
mpagenkoaf801632020-07-03 10:00:42 +0000487 }
488 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
489 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000491 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000492 default:
493 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000494 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495 "msgType": msg.Header.Type, "device-id": dh.deviceID})
496 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000497 }
498 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000499}
500
mpagenkodff5dda2020-08-28 11:52:01 +0000501//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530502func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000503 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
mpagenko01e726e2020-10-23 09:45:29 +0000504 logger.Debugw("FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000505
mpagenko01e726e2020-10-23 09:45:29 +0000506 var retError error = nil
507 //Remove flows (always remove flows first - remove old and add new with same cookie may be part of the same request)
mpagenkodff5dda2020-08-28 11:52:01 +0000508 if apOfFlowChanges.ToRemove != nil {
509 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000510 if flowItem.GetCookie() == 0 {
mpagenko01e726e2020-10-23 09:45:29 +0000511 logger.Warnw("flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
512 "device-id": dh.deviceID})
513 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000514 continue
515 }
516 flowInPort := flow.GetInPort(flowItem)
517 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
mpagenko01e726e2020-10-23 09:45:29 +0000518 logger.Warnw("flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
519 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
520 continue
521 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000522 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000523 //this is some downstream flow, not regarded as error, just ignored
524 logger.Debugw("flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
525 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000526 continue
527 } else {
528 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530529 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000530 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
531 loUniPort = uniPort
532 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000533 logger.Warnw("flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
534 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
535 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
536 flowInPort, dh.deviceID)
537 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000538 }
539 flowOutPort := flow.GetOutPort(flowItem)
mpagenko01e726e2020-10-23 09:45:29 +0000540 logger.Debugw("flow-remove port indications", log.Fields{
541 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000542 "uniPortName": loUniPort.name})
mpagenko01e726e2020-10-23 09:45:29 +0000543 err := dh.removeFlowItemFromUniPort(flowItem, loUniPort)
544 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000545 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000546 logger.Warnw("flow-remove processing error: continuing on checking further flows",
547 log.Fields{"device-id": dh.deviceID, "error": err})
548 retError = err
549 continue
550 //return err
551 } else { // if last setting succeeds, overwrite possibly previously set error
552 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000553 }
554 }
555 }
556 }
mpagenko01e726e2020-10-23 09:45:29 +0000557 if apOfFlowChanges.ToAdd != nil {
558 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
559 if flowItem.GetCookie() == 0 {
560 logger.Debugw("incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
561 "device-id": dh.deviceID})
562 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
563 continue
564 }
565 flowInPort := flow.GetInPort(flowItem)
566 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
567 logger.Warnw("flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
568 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
569 continue
570 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
571 } else if flowInPort == dh.ponPortNumber {
572 //this is some downstream flow
573 logger.Debugw("flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
574 "device-id": dh.deviceID, "inPort": flowInPort})
575 continue
576 } else {
577 // this is the relevant upstream flow
578 var loUniPort *onuUniPort
579 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
580 loUniPort = uniPort
581 } else {
582 logger.Warnw("flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
583 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
584 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
585 flowInPort, dh.deviceID)
586 continue
587 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
588 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000589 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
590 // if not, we just throw some error here to have an indication about that, if we really need to support that
591 // then we would need to create some means to activate the internal stored flows
592 // after the device gets active automatically (and still with its dependency to the TechProfile)
593 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
594 // also abort for the other still possible flows here
595 if !dh.ReadyForSpecificOmciConfig {
596 logger.Warnw("flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
597 "last device-reason": dh.deviceReason})
598 return fmt.Errorf("improper device state on device %s", dh.deviceID)
599 }
600
mpagenko01e726e2020-10-23 09:45:29 +0000601 flowOutPort := flow.GetOutPort(flowItem)
602 logger.Debugw("flow-add port indications", log.Fields{
603 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
604 "uniPortName": loUniPort.name})
605 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
606 //try next flow after processing error
607 if err != nil {
608 logger.Warnw("flow-add processing error: continuing on checking further flows",
609 log.Fields{"device-id": dh.deviceID, "error": err})
610 retError = err
611 continue
612 //return err
613 } else { // if last setting succeeds, overwrite possibly previously set error
614 retError = nil
615 }
616 }
617 }
618 }
619 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000620}
621
Himani Chawla6d2ae152020-09-02 13:11:20 +0530622//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000623//following are the expected device states after this activity:
624//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
625// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530626func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000627 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000628
mpagenko900ee4b2020-10-12 11:56:34 +0000629 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000630 //note that disableDevice sequences in some 'ONU active' state may yield also
631 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000632 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
mpagenko3af1f032020-06-10 08:53:41 +0000633 if dh.deviceReason != "omci-admin-lock" {
mpagenkofc4f56e2020-11-04 17:17:49 +0000634 //disable-device shall be just a UNi/ONU-G related admin state setting
635 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000636
mpagenkofc4f56e2020-11-04 17:17:49 +0000637 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000638 // disable UNI ports/ONU
639 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
640 if dh.pLockStateFsm == nil {
641 dh.createUniLockFsm(true, UniDisableStateDone)
642 } else { //LockStateFSM already init
643 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
644 dh.runUniLockFsm(true)
645 }
646 } else {
647 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
648 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
649 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
650 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
651 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
652 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
653 }
654
655 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
656 "reason": "omci-admin-lock", "device-id": dh.deviceID})
657 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
658 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
659 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
660 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
661 }
662 dh.deviceReason = "omci-admin-lock"
mpagenko3af1f032020-06-10 08:53:41 +0000663 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300664 }
665}
666
Himani Chawla6d2ae152020-09-02 13:11:20 +0530667//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530668func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000669 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000670
mpagenkofc4f56e2020-11-04 17:17:49 +0000671 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
672 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
673 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
674 // for real ONU's that should have nearly no influence
675 // Note that for real ONU's there is anyway a problematic situation with following sequence:
676 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
677 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
678 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
679 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
680
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000681 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000682 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000683 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000684 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000685 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000686 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000687 dh.runUniLockFsm(false)
688 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300689}
690
Himani Chawla6d2ae152020-09-02 13:11:20 +0530691func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000692 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
693
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000694 pDevEntry := dh.getOnuDeviceEntry(true)
695 if pDevEntry == nil {
696 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
697 return
698 }
699 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000700 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
701 dh.reconciling = false
702 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000703 }
Himani Chawla4d908332020-08-31 12:30:20 +0530704 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000705 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
706 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
707 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
708 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530709 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000710}
711
Himani Chawla6d2ae152020-09-02 13:11:20 +0530712func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000713 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
714
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000715 pDevEntry := dh.getOnuDeviceEntry(true)
716 if pDevEntry == nil {
717 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
718 return
719 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000720
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000721 dh.pOnuTP.lockTpProcMutex()
722 defer dh.pOnuTP.unlockTpProcMutex()
723
724 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000725 // deadline context to ensure completion of background routines waited for
726 //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 +0530727 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000728 dctx, cancel := context.WithDeadline(context.Background(), deadline)
729
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000730 dh.pOnuTP.resetTpProcessingErrorIndication()
731
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000732 var wg sync.WaitGroup
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000733 wg.Add(1) // for the 1 go routine to finish
734 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPath, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000735 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000736
737 if err := dh.pOnuTP.getTpProcessingErrorIndication(); err != nil {
738 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
739 }
740 }
741}
742
743func (dh *deviceHandler) reconcileDeviceFlowConfig() {
744 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
745
746 pDevEntry := dh.getOnuDeviceEntry(true)
747 if pDevEntry == nil {
748 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000749 return
750 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000751 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
752 var uniPort *onuUniPort
753 var exist bool
754 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
755 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000756 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000757 return
758 }
759 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000760 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
761 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000762 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000763 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
764 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
765 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000766 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
767 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000768 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000769 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
770 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000771 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000772 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
773 }
774 }
775 }
776 }
777}
778
779func (dh *deviceHandler) reconcileMetrics() {
780 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
781
782 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000783 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000784}
785
Himani Chawla6d2ae152020-09-02 13:11:20 +0530786func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000787 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000788
789 pDevEntry := dh.getOnuDeviceEntry(true)
790 if pDevEntry == nil {
791 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
792 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000793 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 pDevEntry.lockOnuKVStoreMutex()
795 defer pDevEntry.unlockOnuKVStoreMutex()
796
797 // deadline context to ensure completion of background routines waited for
798 //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 +0530799 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000800 dctx, cancel := context.WithDeadline(context.Background(), deadline)
801
802 pDevEntry.resetKvProcessingErrorIndication()
803
804 var wg sync.WaitGroup
805 wg.Add(1) // for the 1 go routine to finish
806 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000807 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000809 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000810 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000811}
812
Himani Chawla6d2ae152020-09-02 13:11:20 +0530813func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000814 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300815 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000816 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000817 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300818 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530819 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530820 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
821 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
822 return err
823 }
mpagenko01e726e2020-10-23 09:45:29 +0000824
825 //transfer the possibly modified logical uni port state
826 dh.disableUniPortStateUpdate()
827
Andrea Campanellabef4e542020-10-22 11:01:28 +0200828 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000829 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200830 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300831 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000832 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000833 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300834 return err
835 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200836 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000837 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000838 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300839 return err
840 }
mpagenko01e726e2020-10-23 09:45:29 +0000841 dh.deviceReason = "rebooting"
mpagenkofc4f56e2020-11-04 17:17:49 +0000842 dh.ReadyForSpecificOmciConfig = false
ozgecanetsiae11479f2020-07-06 09:44:47 +0300843 return nil
844}
845
Himani Chawla6d2ae152020-09-02 13:11:20 +0530846// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000847// #####################################################################################
848
849// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530850// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000851
Himani Chawla6d2ae152020-09-02 13:11:20 +0530852func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000853 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})
854}
855
856// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530857func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000858
859 logger.Debug("doStateInit-started")
860 var err error
861
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000862 // populate what we know. rest comes later after mib sync
863 dh.device.Root = false
864 dh.device.Vendor = "OpenONU"
865 dh.device.Model = "go"
866 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000867 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000868
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000869 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000870
871 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530872 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000873 } else {
874 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
875 log.Fields{"device-id": dh.deviceID})
876 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000877
Himani Chawla4d908332020-08-31 12:30:20 +0530878 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000879 dh.ponPortNumber = dh.device.ParentPortNo
880
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000881 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
882 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
883 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000884 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000885 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530886 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000887
888 /*
889 self._pon = PonPort.create(self, self._pon_port_number)
890 self._pon.add_peer(self.parent_id, self._pon_port_number)
891 self.logger.debug('adding-pon-port-to-agent',
892 type=self._pon.get_port().type,
893 admin_state=self._pon.get_port().admin_state,
894 oper_status=self._pon.get_port().oper_status,
895 )
896 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000897 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000898 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000899 var ponPortNo uint32 = 1
900 if dh.ponPortNumber != 0 {
901 ponPortNo = dh.ponPortNumber
902 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000903
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000904 pPonPort := &voltha.Port{
905 PortNo: ponPortNo,
906 Label: fmt.Sprintf("pon-%d", ponPortNo),
907 Type: voltha.Port_PON_ONU,
908 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530909 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000910 PortNo: ponPortNo}}, // Peer port is parent's port number
911 }
912 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
913 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
914 e.Cancel(err)
915 return
916 }
917 } else {
918 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000919 }
920 logger.Debug("doStateInit-done")
921}
922
923// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530924func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000925
926 logger.Debug("postInit-started")
927 var err error
928 /*
929 dh.Client = oop.NewOpenoltClient(dh.clientCon)
930 dh.pTransitionMap.Handle(ctx, GrpcConnected)
931 return nil
932 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530933 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
934 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000935 e.Cancel(err)
936 return
937 }
938
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000939 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530940 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000941 // reconcilement will be continued after mib download is done
942 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000943 /*
944 ############################################################################
945 # Setup Alarm handler
946 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
947 device.serial_number)
948 ############################################################################
949 # Setup PM configuration for this device
950 # Pass in ONU specific options
951 kwargs = {
952 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
953 'heartbeat': self.heartbeat,
954 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
955 }
956 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
957 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
958 self.logical_device_id, device.serial_number,
959 grouped=True, freq_override=False, **kwargs)
960 pm_config = self._pm_metrics.make_proto()
961 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
962 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
963 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
964
965 # Note, ONU ID and UNI intf set in add_uni_port method
966 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
967 ani_ports=[self._pon])
968
969 # Code to Run OMCI Test Action
970 kwargs_omci_test_action = {
971 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
972 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
973 }
974 serial_number = device.serial_number
975 self._test_request = OmciTestRequest(self.core_proxy,
976 self.omci_agent, self.device_id,
977 AniG, serial_number,
978 self.logical_device_id,
979 exclusive=False,
980 **kwargs_omci_test_action)
981
982 self.enabled = True
983 else:
984 self.logger.info('onu-already-activated')
985 */
986 logger.Debug("postInit-done")
987}
988
989// doStateConnected get the device info and update to voltha core
990// for comparison of the original method (not that easy to uncomment): compare here:
991// voltha-openolt-adapter/adaptercore/device_handler.go
992// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530993func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000994
995 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530996 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000998 logger.Debug("doStateConnected-done")
999}
1000
1001// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301002func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001003
1004 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301005 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001006 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001007 logger.Debug("doStateUp-done")
1008
1009 /*
1010 // Synchronous call to update device state - this method is run in its own go routine
1011 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1012 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001013 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001014 return err
1015 }
1016 return nil
1017 */
1018}
1019
1020// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301021func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001022
1023 logger.Debug("doStateDown-started")
1024 var err error
1025
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001026 device := dh.device
1027 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001028 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001029 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001030 e.Cancel(err)
1031 return
1032 }
1033
1034 cloned := proto.Clone(device).(*voltha.Device)
1035 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1036 /*
1037 // Update the all ports state on that device to disable
1038 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001039 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001040 return er
1041 }
1042
1043 //Update the device oper state and connection status
1044 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1045 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1046 dh.device = cloned
1047
1048 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001049 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050 return er
1051 }
1052
1053 //get the child device for the parent device
1054 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1055 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001056 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001057 return err
1058 }
1059 for _, onuDevice := range onuDevices.Items {
1060
1061 // Update onu state as down in onu adapter
1062 onuInd := oop.OnuIndication{}
1063 onuInd.OperState = "down"
1064 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1065 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1066 if er != nil {
1067 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001068 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069 //Do not return here and continue to process other ONUs
1070 }
1071 }
1072 // * Discovered ONUs entries need to be cleared , since after OLT
1073 // is up, it starts sending discovery indications again* /
1074 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001075 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001076 return nil
1077 */
Himani Chawla4d908332020-08-31 12:30:20 +05301078 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001079 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001080 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001081}
1082
Himani Chawla6d2ae152020-09-02 13:11:20 +05301083// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001084// #################################################################################
1085
1086// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301087// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001088
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001089//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301090func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001091 dh.lockDevice.RLock()
1092 pOnuDeviceEntry := dh.pOnuOmciDevice
1093 if aWait && pOnuDeviceEntry == nil {
1094 //keep the read sema short to allow for subsequent write
1095 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001096 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001097 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1098 // so it might be needed to wait here for that event with some timeout
1099 select {
1100 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001101 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001102 return nil
1103 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001104 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001105 // if written now, we can return the written value without sema
1106 return dh.pOnuOmciDevice
1107 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108 }
mpagenko3af1f032020-06-10 08:53:41 +00001109 dh.lockDevice.RUnlock()
1110 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001111}
1112
Himani Chawla6d2ae152020-09-02 13:11:20 +05301113//setOnuDeviceEntry sets the ONU device entry within the handler
1114func (dh *deviceHandler) setOnuDeviceEntry(
1115 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116 dh.lockDevice.Lock()
1117 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001118 dh.pOnuOmciDevice = apDeviceEntry
1119 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001120}
1121
Himani Chawla6d2ae152020-09-02 13:11:20 +05301122//addOnuDeviceEntry creates a new ONU device or returns the existing
1123func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001124 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125
Himani Chawla6d2ae152020-09-02 13:11:20 +05301126 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001127 if deviceEntry == nil {
1128 /* costum_me_map in python code seems always to be None,
1129 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1130 /* also no 'clock' argument - usage open ...*/
1131 /* and no alarm_db yet (oo.alarm_db) */
Himani Chawla6d2ae152020-09-02 13:11:20 +05301132 deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
mpagenkoaf801632020-07-03 10:00:42 +00001133 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001134 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
mpagenko01e726e2020-10-23 09:45:29 +00001136 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001137 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301138 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001139 // fire deviceEntry ready event to spread to possibly waiting processing
1140 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001141 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001142 } else {
divyadesai4d299552020-08-18 07:13:49 +00001143 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 }
1145 // might be updated with some error handling !!!
1146 return nil
1147}
1148
1149// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301150func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001151 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1152 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1153
1154 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001156 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001157 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1158 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001159 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1160 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1161 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1162 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1163 }
1164 } else {
1165 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1166 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001167 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001168 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1169 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1170 // 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 +00001171 // 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 +00001172 // so let's just try to keep it simple ...
1173 /*
1174 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1175 if err != nil || device == nil {
1176 //TODO: needs to handle error scenarios
1177 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1178 return errors.New("Voltha Device not found")
1179 }
1180 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001181
Himani Chawla6d2ae152020-09-02 13:11:20 +05301182 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001183 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301184 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301185 return err
1186 }
mpagenko3af1f032020-06-10 08:53:41 +00001187 } else {
divyadesai4d299552020-08-18 07:13:49 +00001188 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001189 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001190 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001191 if !dh.reconciling {
1192 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1193 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1194 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1195 }
1196 } else {
1197 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1198 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001199 }
mpagenko3af1f032020-06-10 08:53:41 +00001200 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001201
1202 /* this might be a good time for Omci Verify message? */
1203 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301204 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001205 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001206 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301207 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001208
1209 /* give the handler some time here to wait for the OMCi verification result
1210 after Timeout start and try MibUpload FSM anyway
1211 (to prevent stopping on just not supported OMCI verification from ONU) */
1212 select {
1213 case <-time.After(2 * time.Second):
1214 logger.Warn("omci start-verification timed out (continue normal)")
1215 case testresult := <-verifyExec:
1216 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1217 }
1218
1219 /* In py code it looks earlier (on activate ..)
1220 # Code to Run OMCI Test Action
1221 kwargs_omci_test_action = {
1222 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1223 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1224 }
1225 serial_number = device.serial_number
1226 self._test_request = OmciTestRequest(self.core_proxy,
1227 self.omci_agent, self.device_id,
1228 AniG, serial_number,
1229 self.logical_device_id,
1230 exclusive=False,
1231 **kwargs_omci_test_action)
1232 ...
1233 # Start test requests after a brief pause
1234 if not self._test_request_started:
1235 self._test_request_started = True
1236 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1237 reactor.callLater(tststart, self._test_request.start_collector)
1238
1239 */
1240 /* which is then: in omci_test_request.py : */
1241 /*
1242 def start_collector(self, callback=None):
1243 """
1244 Start the collection loop for an adapter if the frequency > 0
1245
1246 :param callback: (callable) Function to call to collect PM data
1247 """
1248 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1249 if callback is None:
1250 callback = self.perform_test_omci
1251
1252 if self.lc is None:
1253 self.lc = LoopingCall(callback)
1254
1255 if self.default_freq > 0:
1256 self.lc.start(interval=self.default_freq / 10)
1257
1258 def perform_test_omci(self):
1259 """
1260 Perform the initial test request
1261 """
1262 ani_g_entities = self._device.configuration.ani_g_entities
1263 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1264 is not None else None
1265 self._entity_id = ani_g_entities_ids[0]
1266 self.logger.info('perform-test', entity_class=self._entity_class,
1267 entity_id=self._entity_id)
1268 try:
1269 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1270 result = yield self._device.omci_cc.send(frame)
1271 if not result.fields['omci_message'].fields['success_code']:
1272 self.logger.info('Self-Test Submitted Successfully',
1273 code=result.fields[
1274 'omci_message'].fields['success_code'])
1275 else:
1276 raise TestFailure('Test Failure: {}'.format(
1277 result.fields['omci_message'].fields['success_code']))
1278 except TimeoutError as e:
1279 self.deferred.errback(failure.Failure(e))
1280
1281 except Exception as e:
1282 self.logger.exception('perform-test-Error', e=e,
1283 class_id=self._entity_class,
1284 entity_id=self._entity_id)
1285 self.deferred.errback(failure.Failure(e))
1286
1287 */
1288
1289 // PM related heartbeat??? !!!TODO....
1290 //self._heartbeat.enabled = True
1291
mpagenko1cc3cb42020-07-27 15:24:38 +00001292 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1293 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1294 * 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 +05301295 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001296 */
1297 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001298 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001299 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001300 if pMibUlFsm.Is(ulStDisabled) {
1301 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001302 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001303 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301304 }
1305 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1306 //Determine ONU status and start/re-start MIB Synchronization tasks
1307 //Determine if this ONU has ever synchronized
1308 if true { //TODO: insert valid check
1309 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001310 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001311 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001312 }
Himani Chawla4d908332020-08-31 12:30:20 +05301313 } else {
1314 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001315 logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001316 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301317 }
1318 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1319 //Examine the MIB Data Sync
1320 // callbacks to be handled:
1321 // Event(ulEvSuccess)
1322 // Event(ulEvTimeout)
1323 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001324 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001325 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001326 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001327 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001328 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329 }
1330 } else {
divyadesai4d299552020-08-18 07:13:49 +00001331 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001332 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001333 }
1334 return nil
1335}
1336
Himani Chawla6d2ae152020-09-02 13:11:20 +05301337func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001338 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001339 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
mpagenko3af1f032020-06-10 08:53:41 +00001340 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001341 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001342 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1343 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1344 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1345 if err := dh.resetFsms(); err != nil {
1346 logger.Errorw("error-updateInterface at FSM stop",
1347 log.Fields{"device-id": dh.deviceID, "error": err})
1348 // abort: system behavior is just unstable ...
1349 return err
1350 }
1351
1352 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1353 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1354 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301355 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001356 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001357 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001358 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001359 }
mpagenko900ee4b2020-10-12 11:56:34 +00001360 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001361
1362 //TODO!!! remove existing traffic profiles
1363 /* from py code, if TP's exist, remove them - not yet implemented
1364 self._tp = dict()
1365 # Let TP download happen again
1366 for uni_id in self._tp_service_specific_task:
1367 self._tp_service_specific_task[uni_id].clear()
1368 for uni_id in self._tech_profile_download_done:
1369 self._tech_profile_download_done[uni_id].clear()
1370 */
1371
1372 dh.disableUniPortStateUpdate()
1373
mpagenkofc4f56e2020-11-04 17:17:49 +00001374 dh.deviceReason = "stopping-openomci"
1375 dh.ReadyForSpecificOmciConfig = false
1376
mpagenko3af1f032020-06-10 08:53:41 +00001377 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001378 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001379 logger.Errorw("error-DeviceReasonUpdate to stopping-openomci",
divyadesai4d299552020-08-18 07:13:49 +00001380 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001381 // abort: system behavior is just unstable ...
1382 return err
1383 }
mpagenko3af1f032020-06-10 08:53:41 +00001384
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001385 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1386 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001387 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1388 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001389 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001390 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001391 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001392 // abort: system behavior is just unstable ...
1393 return err
1394 }
1395 } else {
divyadesai4d299552020-08-18 07:13:49 +00001396 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001397 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001398 return nil
1399}
1400
mpagenko900ee4b2020-10-12 11:56:34 +00001401func (dh *deviceHandler) resetFsms() error {
1402 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1403 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1404 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1405 // and using the stop/reset event should never harm
1406
1407 pDevEntry := dh.getOnuDeviceEntry(false)
1408 if pDevEntry == nil {
1409 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1410 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1411 }
1412
1413 //the MibSync FSM might be active all the ONU-active time,
1414 // hence it must be stopped unconditionally
1415 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1416 if pMibUlFsm != nil {
1417 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1418 }
1419 //MibDownload may run
1420 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1421 if pMibDlFsm != nil {
1422 _ = pMibDlFsm.Event(dlEvReset)
1423 }
1424 //port lock/unlock FSM's may be active
1425 if dh.pUnlockStateFsm != nil {
1426 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1427 }
1428 if dh.pLockStateFsm != nil {
1429 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1430 }
1431 //techProfile related PonAniConfigFsm FSM may be active
1432 if dh.pOnuTP != nil {
1433 // should always be the case here
1434 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1435 if dh.pOnuTP.pAniConfigFsm != nil {
1436 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1437 }
1438 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001439 // reset the possibly existing VlanConfigFsm
1440 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1441 //VlanFilterFsm exists and was already started
1442 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1443 if pVlanFilterStatemachine != nil {
1444 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1445 }
1446 }
1447 }
1448 }
1449 //TODO!!! care about PM/Alarm processing once started
1450 return nil
1451}
1452
Himani Chawla6d2ae152020-09-02 13:11:20 +05301453func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301454 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1455 if !dh.reconciling {
1456 //initiate DevStateUpdate
1457 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1458 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001459 logger.Errorw("error-DeviceReasonUpdate to mibsync-complete", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301460 "device-id": dh.deviceID, "error": err})
1461 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001462 logger.Infow("dev reason updated to MibSync complete", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301463 }
1464 } else {
1465 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1466 log.Fields{"device-id": dh.deviceID})
1467 }
1468 //set internal state anyway - as it was done
1469 dh.deviceReason = "discovery-mibsync-complete"
1470
1471 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301472 pDevEntry := dh.getOnuDeviceEntry(false)
1473 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301474 for _, mgmtEntityID := range unigInstKeys {
1475 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1476 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301477 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301478 i++
1479 }
1480 } else {
1481 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1482 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301483 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301484 for _, mgmtEntityID := range veipInstKeys {
1485 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1486 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301487 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301488 i++
1489 }
1490 } else {
1491 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1492 }
1493 if i == 0 {
1494 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1495 }
1496
1497 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1498 * left the code here as comment in case such processing should prove needed unexpectedly
1499 // Init Uni Ports to Admin locked state
1500 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1501 // *** should generate UniLockStateDone event *****
1502 if dh.pLockStateFsm == nil {
1503 dh.createUniLockFsm(true, UniLockStateDone)
1504 } else { //LockStateFSM already init
1505 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1506 dh.runUniLockFsm(true)
1507 }
1508 }
1509 case UniLockStateDone:
1510 {
1511 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1512 * lockState processing commented out
1513 */
1514 /* Mib download procedure -
1515 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1516 */
1517 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1518 if pMibDlFsm != nil {
1519 if pMibDlFsm.Is(dlStDisabled) {
1520 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001521 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301522 // maybe try a FSM reset and then again ... - TODO!!!
1523 } else {
1524 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1525 // maybe use more specific states here for the specific download steps ...
1526 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001527 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301528 } else {
1529 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1530 //Begin MIB data download (running autonomously)
1531 }
1532 }
1533 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001534 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001535 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301536 // maybe try a FSM reset and then again ... - TODO!!!
1537 }
1538 /***** Mib download started */
1539 } else {
1540 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1541 }
1542}
1543
Himani Chawla6d2ae152020-09-02 13:11:20 +05301544func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301545 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1546 //initiate DevStateUpdate
1547 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001548 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1549 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301550 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1551 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1552 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1553 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1554 } else {
1555 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1556 }
1557 } else {
1558 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1559 log.Fields{"device-id": dh.deviceID})
1560 }
1561 if !dh.reconciling {
1562 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1563 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001564 logger.Errorw("error-DeviceReasonUpdate to initial-mib-downloaded",
Himani Chawla26e555c2020-08-31 12:30:20 +05301565 log.Fields{"device-id": dh.deviceID, "error": err})
1566 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001567 logger.Infow("dev reason updated to initial-mib-downloaded", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301568 }
1569 } else {
1570 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1571 log.Fields{"device-id": dh.deviceID})
1572 }
1573 //set internal state anyway - as it was done
1574 dh.deviceReason = "initial-mib-downloaded"
mpagenkofc4f56e2020-11-04 17:17:49 +00001575 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301576 // *** should generate UniUnlockStateDone event *****
1577 if dh.pUnlockStateFsm == nil {
1578 dh.createUniLockFsm(false, UniUnlockStateDone)
1579 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301580 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301581 dh.runUniLockFsm(false)
1582 }
1583}
1584
Himani Chawla6d2ae152020-09-02 13:11:20 +05301585func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001586 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301587
1588 if !dh.reconciling {
1589 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1590 raisedTs := time.Now().UnixNano()
1591 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1592 } else {
1593 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1594 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301595 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001596 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301597 }
1598}
1599
mpagenko900ee4b2020-10-12 11:56:34 +00001600func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1601 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1602 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1603 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1604 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1605 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1606 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1607 }
1608
mpagenkofc4f56e2020-11-04 17:17:49 +00001609 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{
mpagenko900ee4b2020-10-12 11:56:34 +00001610 "reason": "omci-admin-lock", "device-id": dh.deviceID})
1611 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1612 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
1613 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1614 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1615 }
1616 dh.deviceReason = "omci-admin-lock"
1617
1618 //transfer the modified logical uni port state
1619 dh.disableUniPortStateUpdate()
mpagenko900ee4b2020-10-12 11:56:34 +00001620}
1621
1622func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1623 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1624 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1625 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1626 voltha.OperStatus_ACTIVE); err != nil {
1627 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1628 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1629 }
1630
1631 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1632 "reason": "onu-reenabled", "device-id": dh.deviceID})
1633 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1634 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
1635 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1636 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1637 }
1638 dh.deviceReason = "onu-reenabled"
1639
1640 //transfer the modified logical uni port state
1641 dh.enableUniPortStateUpdate()
1642}
1643
Himani Chawla6d2ae152020-09-02 13:11:20 +05301644func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001645 if devEvent == OmciAniConfigDone {
1646 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1647 // attention: the device reason update is done based on ONU-UNI-Port related activity
1648 // - which may cause some inconsistency
1649 if dh.deviceReason != "tech-profile-config-download-success" {
1650 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
1651 if !dh.reconciling {
1652 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1653 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1654 logger.Errorw("error-DeviceReasonUpdate to tech-profile-config-download-success",
1655 log.Fields{"device-id": dh.deviceID, "error": err})
1656 } else {
1657 logger.Infow("update dev reason to tech-profile-config-download-success",
1658 log.Fields{"device-id": dh.deviceID})
1659 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301660 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001661 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
Himani Chawla26e555c2020-08-31 12:30:20 +05301662 log.Fields{"device-id": dh.deviceID})
1663 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001664 //set internal state anyway - as it was done
1665 dh.deviceReason = "tech-profile-config-download-success"
Himani Chawla26e555c2020-08-31 12:30:20 +05301666 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001667 if dh.reconciling {
1668 go dh.reconcileDeviceFlowConfig()
1669 }
1670 } else { // should be the OmciAniResourceRemoved block
1671 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1672 // attention: the device reason update is done based on ONU-UNI-Port related activity
1673 // - which may cause some inconsistency
1674 if dh.deviceReason != "tech-profile-config-delete-success" {
1675 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
1676 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-delete-success"); err != nil {
1677 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1678 logger.Errorw("error-DeviceReasonUpdate to tech-profile-config-delete-success",
1679 log.Fields{"device-id": dh.deviceID, "error": err})
1680 } else {
1681 logger.Infow("update dev reason to tech-profile-config-delete-success",
1682 log.Fields{"device-id": dh.deviceID})
1683 }
1684 //set internal state anyway - as it was done
1685 dh.deviceReason = "tech-profile-config-delete-success"
1686 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001687 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301688}
1689
mpagenkofc4f56e2020-11-04 17:17:49 +00001690func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301691 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001692 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301693 // attention: the device reason update is done based on ONU-UNI-Port related activity
1694 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301695
mpagenkofc4f56e2020-11-04 17:17:49 +00001696 if aDevEvent == OmciVlanFilterAddDone {
1697 if dh.deviceReason != "omci-flows-pushed" {
1698 // which may be the case from some previous actvity on another UNI Port of the ONU
1699 // or even some previous flow add activity on the same port
1700 if !dh.reconciling {
1701 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1702 logger.Errorw("error-DeviceReasonUpdate to omci-flows-pushed",
1703 log.Fields{"device-id": dh.deviceID, "error": err})
1704 } else {
1705 logger.Infow("updated dev reason to omci-flows-pushed",
1706 log.Fields{"device-id": dh.deviceID})
1707 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001708 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001709 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001710 log.Fields{"device-id": dh.deviceID})
1711 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001712 //set internal state anyway - as it was done
1713 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001714
mpagenkofc4f56e2020-11-04 17:17:49 +00001715 if dh.reconciling {
1716 go dh.reconcileMetrics()
1717 }
1718 }
1719 } else {
1720 if dh.deviceReason != "omci-flows-deleted" {
1721 //not relevant for reconcile
1722 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-deleted"); err != nil {
1723 logger.Errorw("error-DeviceReasonUpdate to omci-flows-deleted",
1724 log.Fields{"device-id": dh.deviceID, "error": err})
1725 } else {
1726 logger.Infow("updated dev reason to omci-flows-deleted",
1727 log.Fields{"device-id": dh.deviceID})
1728 }
1729 //set internal state anyway - as it was done
1730 dh.deviceReason = "omci-flows-deleted"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001731 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301732 }
1733}
1734
Himani Chawla6d2ae152020-09-02 13:11:20 +05301735//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1736func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301737 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001738 case MibDatabaseSync:
1739 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301740 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001741 }
1742 case MibDownloadDone:
1743 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301744 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001745 }
1746 case UniUnlockStateDone:
1747 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301748 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001749 }
mpagenko900ee4b2020-10-12 11:56:34 +00001750 case UniEnableStateDone:
1751 {
1752 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001753 }
1754 case UniDisableStateDone:
1755 {
1756 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001757 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001758 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001759 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301760 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001761 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001762 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001763 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301764 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001765 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001766 default:
1767 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001768 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001769 }
1770 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001771}
1772
Himani Chawla6d2ae152020-09-02 13:11:20 +05301773func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001774 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301775 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301776 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001777 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301778 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001779 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301780 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301781 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001782 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301783 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001784 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001785 //store UniPort with the System-PortNumber key
1786 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001787 if !dh.reconciling {
1788 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301789 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001790 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1791 } //error logging already within UniPort method
1792 } else {
1793 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1794 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001795 }
1796 }
1797}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001798
mpagenko3af1f032020-06-10 08:53:41 +00001799// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301800func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001801 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301802 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001803 // with following remark:
1804 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1805 // # load on the core
1806
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001807 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001808
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001809 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001810 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301811 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001812 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301813 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001814 if !dh.reconciling {
1815 //maybe also use getter functions on uniPort - perhaps later ...
1816 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1817 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001818 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001819 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1820 }
mpagenko3af1f032020-06-10 08:53:41 +00001821 }
1822 }
1823}
1824
1825// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301826func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001827 // compare enableUniPortStateUpdate() above
1828 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1829 for uniNo, uniPort := range dh.uniEntityMap {
1830 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301831 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001832 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301833 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001834 //maybe also use getter functions on uniPort - perhaps later ...
1835 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001836 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001837 }
1838}
1839
1840// ONU_Active/Inactive announcement on system KAFKA bus
1841// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301842func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001843 var de voltha.DeviceEvent
1844 eventContext := make(map[string]string)
1845 //Populating event context
1846 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301847 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001848 if err != nil || parentDevice == nil {
1849 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301850 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001851 }
1852 oltSerialNumber := parentDevice.SerialNumber
1853
1854 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1855 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1856 eventContext["serial-number"] = dh.device.SerialNumber
1857 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301858 eventContext["device_id"] = aDeviceID
1859 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001860 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001861 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001862
1863 /* Populating device event body */
1864 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301865 de.ResourceId = aDeviceID
1866 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001867 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1868 de.Description = fmt.Sprintf("%s Event - %s - %s",
1869 cEventObjectType, cOnuActivatedEvent, "Raised")
1870 } else {
1871 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1872 de.Description = fmt.Sprintf("%s Event - %s - %s",
1873 cEventObjectType, cOnuActivatedEvent, "Cleared")
1874 }
1875 /* Send event to KAFKA */
1876 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1877 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301878 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001879 }
1880 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301881 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001882}
1883
Himani Chawla4d908332020-08-31 12:30:20 +05301884// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301885func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001886 chLSFsm := make(chan Message, 2048)
1887 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301888 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001889 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001890 sFsmName = "LockStateFSM"
1891 } else {
divyadesai4d299552020-08-18 07:13:49 +00001892 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001893 sFsmName = "UnLockStateFSM"
1894 }
mpagenko3af1f032020-06-10 08:53:41 +00001895
Himani Chawla6d2ae152020-09-02 13:11:20 +05301896 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001897 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001898 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001899 return
1900 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301901 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001902 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001903 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301904 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001905 dh.pLockStateFsm = pLSFsm
1906 } else {
1907 dh.pUnlockStateFsm = pLSFsm
1908 }
1909 dh.runUniLockFsm(aAdminState)
1910 } else {
divyadesai4d299552020-08-18 07:13:49 +00001911 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001912 }
1913}
1914
1915// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301916func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001917 /* Uni Port lock/unlock procedure -
1918 ***** should run via 'adminDone' state and generate the argument requested event *****
1919 */
1920 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301921 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001922 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1923 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1924 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001925 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301926 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001927 }
1928 } else {
1929 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1930 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1931 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001932 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301933 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001934 }
1935 }
1936 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001937 if pLSStatemachine.Is(uniStDisabled) {
1938 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001939 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1940 // maybe try a FSM reset and then again ... - TODO!!!
1941 } else {
1942 /***** LockStateFSM started */
1943 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001944 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001945 }
1946 } else {
1947 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001948 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001949 // maybe try a FSM reset and then again ... - TODO!!!
1950 }
1951 } else {
divyadesai4d299552020-08-18 07:13:49 +00001952 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001953 // maybe try a FSM reset and then again ... - TODO!!!
1954 }
1955}
1956
Himani Chawla6d2ae152020-09-02 13:11:20 +05301957//setBackend provides a DB backend for the specified path on the existing KV client
1958func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001959 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1960 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001961 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001962 kvbackend := &db.Backend{
1963 Client: dh.pOpenOnuAc.kvClient,
1964 StoreType: dh.pOpenOnuAc.KVStoreType,
1965 /* address config update acc. to [VOL-2736] */
1966 Address: addr,
1967 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1968 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001969
mpagenkoaf801632020-07-03 10:00:42 +00001970 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001971}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301972func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301973 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001974
mpagenkodff5dda2020-08-28 11:52:01 +00001975 for _, field := range flow.GetOfbFields(apFlowItem) {
1976 switch field.Type {
1977 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1978 {
mpagenko01e726e2020-10-23 09:45:29 +00001979 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001980 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1981 }
mpagenko01e726e2020-10-23 09:45:29 +00001982 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00001983 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1984 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301985 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00001986 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301987 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1988 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001989 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1990 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00001991 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
1992 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301993 return
mpagenkodff5dda2020-08-28 11:52:01 +00001994 }
1995 }
mpagenko01e726e2020-10-23 09:45:29 +00001996 */
mpagenkodff5dda2020-08-28 11:52:01 +00001997 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1998 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301999 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002000 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302001 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002002 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302003 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002004 }
mpagenko01e726e2020-10-23 09:45:29 +00002005 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302006 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002007 }
2008 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2009 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302010 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002011 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002012 "PCP": loAddPcp})
2013 }
2014 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2015 {
mpagenko01e726e2020-10-23 09:45:29 +00002016 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002017 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2018 }
2019 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2020 {
mpagenko01e726e2020-10-23 09:45:29 +00002021 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002022 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2023 }
2024 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2025 {
mpagenko01e726e2020-10-23 09:45:29 +00002026 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002027 "IPv4-DST": field.GetIpv4Dst()})
2028 }
2029 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2030 {
mpagenko01e726e2020-10-23 09:45:29 +00002031 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002032 "IPv4-SRC": field.GetIpv4Src()})
2033 }
2034 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2035 {
mpagenko01e726e2020-10-23 09:45:29 +00002036 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002037 "Metadata": field.GetTableMetadata()})
2038 }
2039 /*
2040 default:
2041 {
2042 //all other entires ignored
2043 }
2044 */
2045 }
2046 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302047}
mpagenkodff5dda2020-08-28 11:52:01 +00002048
Himani Chawla6d2ae152020-09-02 13:11:20 +05302049func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002050 for _, action := range flow.GetActions(apFlowItem) {
2051 switch action.Type {
2052 /* not used:
2053 case of.OfpActionType_OFPAT_OUTPUT:
2054 {
mpagenko01e726e2020-10-23 09:45:29 +00002055 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002056 "Output": action.GetOutput()})
2057 }
2058 */
2059 case of.OfpActionType_OFPAT_PUSH_VLAN:
2060 {
mpagenko01e726e2020-10-23 09:45:29 +00002061 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002062 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2063 }
2064 case of.OfpActionType_OFPAT_SET_FIELD:
2065 {
2066 pActionSetField := action.GetSetField()
2067 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00002068 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002069 "OxcmClass": pActionSetField.Field.OxmClass})
2070 }
2071 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302072 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002073 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302074 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002075 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302076 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002077 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302078 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002079 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002080 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002081 "Type": pActionSetField.Field.GetOfbField().Type})
2082 }
2083 }
2084 /*
2085 default:
2086 {
2087 //all other entires ignored
2088 }
2089 */
2090 }
2091 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302092}
2093
2094//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302095func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302096 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2097 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2098 var loAddPcp, loSetPcp uint8
2099 var loIPProto uint32
2100 /* the TechProfileId is part of the flow Metadata - compare also comment within
2101 * OLT-Adapter:openolt_flowmgr.go
2102 * Metadata 8 bytes:
2103 * Most Significant 2 Bytes = Inner VLAN
2104 * Next 2 Bytes = Tech Profile ID(TPID)
2105 * Least Significant 4 Bytes = Port ID
2106 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2107 * subscriber related flows.
2108 */
2109
2110 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2111 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002112 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302113 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002114 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302115 }
2116 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002117 loCookie := apFlowItem.GetCookie()
2118 loCookieSlice := []uint64{loCookie}
2119 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2120 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302121
2122 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002123 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302124 if loIPProto == 2 {
2125 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2126 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002127 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2128 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302129 return nil
2130 }
mpagenko01e726e2020-10-23 09:45:29 +00002131 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302132 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002133
2134 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002135 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002136 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2137 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2138 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2139 //TODO!!: Use DeviceId within the error response to rwCore
2140 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002141 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002142 }
2143 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002144 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002145 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2146 } else {
2147 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2148 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2149 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302150 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002151 }
mpagenko01e726e2020-10-23 09:45:29 +00002152 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002153 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302154 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002155 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2156 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002157 }
mpagenko01e726e2020-10-23 09:45:29 +00002158 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002159 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002160}
2161
2162//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2163func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2164 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2165 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2166 //no extra check is done on the rule parameters
2167 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2168 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2169 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2170 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002171 // - some possible 'delete-all' sequence would have to be implemented separately (where the cookies are don't care anyway)
mpagenko01e726e2020-10-23 09:45:29 +00002172 loCookie := apFlowItem.GetCookie()
2173 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2174
2175 /* TT related temporary workaround - should not be needed anymore
2176 for _, field := range flow.GetOfbFields(apFlowItem) {
2177 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2178 loIPProto := field.GetIpProto()
2179 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2180 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2181 if loIPProto == 2 {
2182 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2183 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2184 log.Fields{"device-id": dh.deviceID})
2185 return nil
2186 }
2187 }
2188 } //for all OfbFields
2189 */
2190
2191 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2192 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2193 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002194 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002195 log.Fields{"device-id": dh.deviceID})
2196 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002197 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2198 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2199
mpagenko01e726e2020-10-23 09:45:29 +00002200 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002201}
2202
Himani Chawla26e555c2020-08-31 12:30:20 +05302203// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002204func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2205 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002206 chVlanFilterFsm := make(chan Message, 2048)
2207
Himani Chawla6d2ae152020-09-02 13:11:20 +05302208 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002209 if pDevEntry == nil {
2210 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302211 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002212 }
2213
2214 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002215 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2216 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002217 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302218 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002219 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2220 if pVlanFilterStatemachine != nil {
2221 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2222 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2223 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302224 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002225 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302226 /***** UniVlanConfigFsm started */
2227 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2228 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2229 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002230 } else {
2231 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2232 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302233 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002234 }
2235 } else {
2236 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2237 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302238 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002239 }
2240 } else {
2241 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2242 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302243 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002244 }
2245 return nil
2246}
2247
mpagenkofc4f56e2020-11-04 17:17:49 +00002248//VerifyVlanConfigRequest checks on existence of a given uniPort
2249// and starts verification of flow config based on that
2250func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2251 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2252 var pCurrentUniPort *onuUniPort
2253 for _, uniPort := range dh.uniEntityMap {
2254 // only if this port is validated for operState transfer
2255 if uniPort.uniID == uint8(aUniID) {
2256 pCurrentUniPort = uniPort
2257 break //found - end search loop
2258 }
2259 }
2260 if pCurrentUniPort == nil {
2261 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2262 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2263 return
2264 }
2265 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2266}
2267
mpagenkodff5dda2020-08-28 11:52:01 +00002268//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302269func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002270 //TODO!! verify and start pending flow configuration
2271 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2272 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302273 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002274 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2275 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2276 if pVlanFilterStatemachine != nil {
2277 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2278 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2279 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2280 } else {
2281 /***** UniVlanConfigFsm continued */
2282 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2283 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2284 "UniPort": apUniPort.portNo})
2285 }
2286 } else {
2287 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2288 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2289 }
2290 } else {
2291 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2292 "device-id": dh.deviceID})
2293 }
2294
2295 } // else: nothing to do
2296}
2297
2298//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2299// 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 +05302300func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002301 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2302 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2303 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302304 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002305}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002306
2307//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2308//available for potential reconcilement
2309
2310func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2311
2312 if dh.reconciling {
2313 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2314 return nil
2315 }
2316 logger.Debugw("Store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2317
2318 pDevEntry := dh.getOnuDeviceEntry(true)
2319 if pDevEntry == nil {
2320 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2321 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2322 }
2323 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2324
2325 pDevEntry.lockOnuKVStoreMutex()
2326 defer pDevEntry.unlockOnuKVStoreMutex()
2327
2328 // deadline context to ensure completion of background routines waited for
2329 //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 +05302330 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002331 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2332
2333 pDevEntry.resetKvProcessingErrorIndication()
2334 var wg sync.WaitGroup
2335 wg.Add(1) // for the 1 go routine to finish
2336
2337 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002338 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002339
2340 return pDevEntry.getKvProcessingErrorIndication()
2341}
2342
mpagenko01e726e2020-10-23 09:45:29 +00002343func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002344 defer cancel() //ensure termination of context (may be pro forma)
2345 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002346 logger.Debugw("WaitGroup processing completed", log.Fields{
2347 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002348}
2349
2350func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2351 var errStr string = ""
2352 for _, err := range errS {
2353 if err != nil {
2354 errStr = errStr + err.Error() + " "
2355 }
2356 }
2357 if errStr != "" {
2358 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2359 }
2360 return nil
2361}