blob: 13f5ec59defc42cca768c7c4f7302b1e72cf8afb [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 ...
mpagenkoa40e99a2020-11-17 13:50:39 +0000285 logger.Errorw("onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530286 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 {
mpagenkoa40e99a2020-11-17 13:50:39 +0000290 logger.Errorw("TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000291 "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 {
mpagenkoa40e99a2020-11-17 13:50:39 +0000596 logger.Errorw("flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000597 "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
mpagenko2418ab02020-11-12 12:58:06 +0000655 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000656 "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 {
mpagenko2418ab02020-11-12 12:58:06 +0000700 if err == fmt.Errorf("no-ONU-data-found") {
701 logger.Debugw("no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
702 } else {
703 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
704 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000705 dh.reconciling = false
706 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000707 }
Himani Chawla4d908332020-08-31 12:30:20 +0530708 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000709 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
710 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
711 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
712 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530713 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000714}
715
Himani Chawla6d2ae152020-09-02 13:11:20 +0530716func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000717 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
718
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000719 pDevEntry := dh.getOnuDeviceEntry(true)
720 if pDevEntry == nil {
721 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
722 return
723 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000724
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000725 dh.pOnuTP.lockTpProcMutex()
726 defer dh.pOnuTP.unlockTpProcMutex()
727
728 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000729 // deadline context to ensure completion of background routines waited for
730 //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 +0530731 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000732 dctx, cancel := context.WithDeadline(context.Background(), deadline)
733
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000734 dh.pOnuTP.resetTpProcessingErrorIndication()
735
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000736 var wg sync.WaitGroup
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000737 wg.Add(1) // for the 1 go routine to finish
738 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPath, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000739 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000740
741 if err := dh.pOnuTP.getTpProcessingErrorIndication(); err != nil {
742 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
743 }
744 }
745}
746
747func (dh *deviceHandler) reconcileDeviceFlowConfig() {
748 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
749
750 pDevEntry := dh.getOnuDeviceEntry(true)
751 if pDevEntry == nil {
752 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000753 return
754 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000755 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
756 var uniPort *onuUniPort
757 var exist bool
758 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
759 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000760 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000761 return
762 }
763 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000764 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
765 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000766 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000767 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
768 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
769 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000770 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
771 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000772 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000773 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
774 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000775 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000776 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
777 }
778 }
779 }
780 }
781}
782
783func (dh *deviceHandler) reconcileMetrics() {
784 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
785
786 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000787 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000788}
789
mpagenko2418ab02020-11-12 12:58:06 +0000790func (dh *deviceHandler) deleteDevicePersistencyData() error {
791 logger.Debugw("delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792
mpagenko2418ab02020-11-12 12:58:06 +0000793 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000795 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
796 logger.Debugw("OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
797 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000798 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000799 pDevEntry.lockOnuKVStoreMutex()
800 defer pDevEntry.unlockOnuKVStoreMutex()
801
802 // deadline context to ensure completion of background routines waited for
803 //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 +0530804 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000805 dctx, cancel := context.WithDeadline(context.Background(), deadline)
806
807 pDevEntry.resetKvProcessingErrorIndication()
808
809 var wg sync.WaitGroup
810 wg.Add(1) // for the 1 go routine to finish
811 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000812 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000813
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000814 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000815 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000816}
817
Himani Chawla6d2ae152020-09-02 13:11:20 +0530818func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000819 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300820 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000821 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000822 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300823 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530824 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530825 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
826 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
827 return err
828 }
mpagenko01e726e2020-10-23 09:45:29 +0000829
830 //transfer the possibly modified logical uni port state
831 dh.disableUniPortStateUpdate()
832
Andrea Campanellabef4e542020-10-22 11:01:28 +0200833 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000834 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200835 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300836 voltha.OperStatus_DISCOVERED); 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-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300839 return err
840 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200841 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000842 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000843 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300844 return err
845 }
mpagenko01e726e2020-10-23 09:45:29 +0000846 dh.deviceReason = "rebooting"
mpagenkofc4f56e2020-11-04 17:17:49 +0000847 dh.ReadyForSpecificOmciConfig = false
ozgecanetsiae11479f2020-07-06 09:44:47 +0300848 return nil
849}
850
Himani Chawla6d2ae152020-09-02 13:11:20 +0530851// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000852// #####################################################################################
853
854// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530855// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000856
Himani Chawla6d2ae152020-09-02 13:11:20 +0530857func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000858 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})
859}
860
861// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530862func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000863
864 logger.Debug("doStateInit-started")
865 var err error
866
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000867 // populate what we know. rest comes later after mib sync
868 dh.device.Root = false
869 dh.device.Vendor = "OpenONU"
870 dh.device.Model = "go"
871 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000872 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000873
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000874 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000875
876 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530877 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000878 } else {
879 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
880 log.Fields{"device-id": dh.deviceID})
881 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000882
Himani Chawla4d908332020-08-31 12:30:20 +0530883 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000884 dh.ponPortNumber = dh.device.ParentPortNo
885
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000886 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
887 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
888 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000889 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000890 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530891 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000892
893 /*
894 self._pon = PonPort.create(self, self._pon_port_number)
895 self._pon.add_peer(self.parent_id, self._pon_port_number)
896 self.logger.debug('adding-pon-port-to-agent',
897 type=self._pon.get_port().type,
898 admin_state=self._pon.get_port().admin_state,
899 oper_status=self._pon.get_port().oper_status,
900 )
901 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000902 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000903 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000904 var ponPortNo uint32 = 1
905 if dh.ponPortNumber != 0 {
906 ponPortNo = dh.ponPortNumber
907 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000908
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000909 pPonPort := &voltha.Port{
910 PortNo: ponPortNo,
911 Label: fmt.Sprintf("pon-%d", ponPortNo),
912 Type: voltha.Port_PON_ONU,
913 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530914 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000915 PortNo: ponPortNo}}, // Peer port is parent's port number
916 }
917 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
918 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
919 e.Cancel(err)
920 return
921 }
922 } else {
923 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000924 }
925 logger.Debug("doStateInit-done")
926}
927
928// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530929func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000930
931 logger.Debug("postInit-started")
932 var err error
933 /*
934 dh.Client = oop.NewOpenoltClient(dh.clientCon)
935 dh.pTransitionMap.Handle(ctx, GrpcConnected)
936 return nil
937 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530938 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
939 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000940 e.Cancel(err)
941 return
942 }
943
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000944 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530945 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000946 // reconcilement will be continued after mib download is done
947 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000948 /*
949 ############################################################################
950 # Setup Alarm handler
951 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
952 device.serial_number)
953 ############################################################################
954 # Setup PM configuration for this device
955 # Pass in ONU specific options
956 kwargs = {
957 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
958 'heartbeat': self.heartbeat,
959 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
960 }
961 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
962 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
963 self.logical_device_id, device.serial_number,
964 grouped=True, freq_override=False, **kwargs)
965 pm_config = self._pm_metrics.make_proto()
966 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
967 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
968 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
969
970 # Note, ONU ID and UNI intf set in add_uni_port method
971 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
972 ani_ports=[self._pon])
973
974 # Code to Run OMCI Test Action
975 kwargs_omci_test_action = {
976 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
977 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
978 }
979 serial_number = device.serial_number
980 self._test_request = OmciTestRequest(self.core_proxy,
981 self.omci_agent, self.device_id,
982 AniG, serial_number,
983 self.logical_device_id,
984 exclusive=False,
985 **kwargs_omci_test_action)
986
987 self.enabled = True
988 else:
989 self.logger.info('onu-already-activated')
990 */
991 logger.Debug("postInit-done")
992}
993
994// doStateConnected get the device info and update to voltha core
995// for comparison of the original method (not that easy to uncomment): compare here:
996// voltha-openolt-adapter/adaptercore/device_handler.go
997// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530998func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000999
1000 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301001 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001002 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001003 logger.Debug("doStateConnected-done")
1004}
1005
1006// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301007func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001008
1009 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301010 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001011 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001012 logger.Debug("doStateUp-done")
1013
1014 /*
1015 // Synchronous call to update device state - this method is run in its own go routine
1016 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1017 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001018 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 +00001019 return err
1020 }
1021 return nil
1022 */
1023}
1024
1025// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301026func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001027
1028 logger.Debug("doStateDown-started")
1029 var err error
1030
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001031 device := dh.device
1032 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001033 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001034 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001035 e.Cancel(err)
1036 return
1037 }
1038
1039 cloned := proto.Clone(device).(*voltha.Device)
1040 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1041 /*
1042 // Update the all ports state on that device to disable
1043 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001044 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001045 return er
1046 }
1047
1048 //Update the device oper state and connection status
1049 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1050 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1051 dh.device = cloned
1052
1053 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001054 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001055 return er
1056 }
1057
1058 //get the child device for the parent device
1059 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1060 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001061 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001062 return err
1063 }
1064 for _, onuDevice := range onuDevices.Items {
1065
1066 // Update onu state as down in onu adapter
1067 onuInd := oop.OnuIndication{}
1068 onuInd.OperState = "down"
1069 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1070 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1071 if er != nil {
1072 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001073 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074 //Do not return here and continue to process other ONUs
1075 }
1076 }
1077 // * Discovered ONUs entries need to be cleared , since after OLT
1078 // is up, it starts sending discovery indications again* /
1079 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001080 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001081 return nil
1082 */
Himani Chawla4d908332020-08-31 12:30:20 +05301083 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001084 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001085 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001086}
1087
Himani Chawla6d2ae152020-09-02 13:11:20 +05301088// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001089// #################################################################################
1090
1091// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301092// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001093
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001094//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301095func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001096 dh.lockDevice.RLock()
1097 pOnuDeviceEntry := dh.pOnuOmciDevice
1098 if aWait && pOnuDeviceEntry == nil {
1099 //keep the read sema short to allow for subsequent write
1100 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001101 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001102 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1103 // so it might be needed to wait here for that event with some timeout
1104 select {
1105 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001106 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001107 return nil
1108 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001109 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001110 // if written now, we can return the written value without sema
1111 return dh.pOnuOmciDevice
1112 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001113 }
mpagenko3af1f032020-06-10 08:53:41 +00001114 dh.lockDevice.RUnlock()
1115 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116}
1117
Himani Chawla6d2ae152020-09-02 13:11:20 +05301118//setOnuDeviceEntry sets the ONU device entry within the handler
1119func (dh *deviceHandler) setOnuDeviceEntry(
1120 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001121 dh.lockDevice.Lock()
1122 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001123 dh.pOnuOmciDevice = apDeviceEntry
1124 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125}
1126
Himani Chawla6d2ae152020-09-02 13:11:20 +05301127//addOnuDeviceEntry creates a new ONU device or returns the existing
1128func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001129 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001130
Himani Chawla6d2ae152020-09-02 13:11:20 +05301131 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132 if deviceEntry == nil {
1133 /* costum_me_map in python code seems always to be None,
1134 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1135 /* also no 'clock' argument - usage open ...*/
1136 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001137 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001138 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001139 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301140 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001141 // fire deviceEntry ready event to spread to possibly waiting processing
1142 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001143 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 } else {
divyadesai4d299552020-08-18 07:13:49 +00001145 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146 }
1147 // might be updated with some error handling !!!
1148 return nil
1149}
1150
1151// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301152func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001153 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1154 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1155
1156 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001157
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001158 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001159 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1160 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001161 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1162 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1163 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1164 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1165 }
1166 } else {
1167 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1168 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001169 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001170 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1171 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1172 // 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 +00001173 // 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 +00001174 // so let's just try to keep it simple ...
1175 /*
1176 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1177 if err != nil || device == nil {
1178 //TODO: needs to handle error scenarios
1179 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1180 return errors.New("Voltha Device not found")
1181 }
1182 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183
Himani Chawla6d2ae152020-09-02 13:11:20 +05301184 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001185 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301186 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301187 return err
1188 }
mpagenko3af1f032020-06-10 08:53:41 +00001189 } else {
divyadesai4d299552020-08-18 07:13:49 +00001190 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001191 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001192 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001193 if !dh.reconciling {
1194 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1195 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1196 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1197 }
1198 } else {
1199 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1200 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001201 }
mpagenko3af1f032020-06-10 08:53:41 +00001202 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203
1204 /* this might be a good time for Omci Verify message? */
1205 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301206 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001207 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001208 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301209 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001210
1211 /* give the handler some time here to wait for the OMCi verification result
1212 after Timeout start and try MibUpload FSM anyway
1213 (to prevent stopping on just not supported OMCI verification from ONU) */
1214 select {
1215 case <-time.After(2 * time.Second):
1216 logger.Warn("omci start-verification timed out (continue normal)")
1217 case testresult := <-verifyExec:
1218 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1219 }
1220
1221 /* In py code it looks earlier (on activate ..)
1222 # Code to Run OMCI Test Action
1223 kwargs_omci_test_action = {
1224 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1225 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1226 }
1227 serial_number = device.serial_number
1228 self._test_request = OmciTestRequest(self.core_proxy,
1229 self.omci_agent, self.device_id,
1230 AniG, serial_number,
1231 self.logical_device_id,
1232 exclusive=False,
1233 **kwargs_omci_test_action)
1234 ...
1235 # Start test requests after a brief pause
1236 if not self._test_request_started:
1237 self._test_request_started = True
1238 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1239 reactor.callLater(tststart, self._test_request.start_collector)
1240
1241 */
1242 /* which is then: in omci_test_request.py : */
1243 /*
1244 def start_collector(self, callback=None):
1245 """
1246 Start the collection loop for an adapter if the frequency > 0
1247
1248 :param callback: (callable) Function to call to collect PM data
1249 """
1250 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1251 if callback is None:
1252 callback = self.perform_test_omci
1253
1254 if self.lc is None:
1255 self.lc = LoopingCall(callback)
1256
1257 if self.default_freq > 0:
1258 self.lc.start(interval=self.default_freq / 10)
1259
1260 def perform_test_omci(self):
1261 """
1262 Perform the initial test request
1263 """
1264 ani_g_entities = self._device.configuration.ani_g_entities
1265 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1266 is not None else None
1267 self._entity_id = ani_g_entities_ids[0]
1268 self.logger.info('perform-test', entity_class=self._entity_class,
1269 entity_id=self._entity_id)
1270 try:
1271 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1272 result = yield self._device.omci_cc.send(frame)
1273 if not result.fields['omci_message'].fields['success_code']:
1274 self.logger.info('Self-Test Submitted Successfully',
1275 code=result.fields[
1276 'omci_message'].fields['success_code'])
1277 else:
1278 raise TestFailure('Test Failure: {}'.format(
1279 result.fields['omci_message'].fields['success_code']))
1280 except TimeoutError as e:
1281 self.deferred.errback(failure.Failure(e))
1282
1283 except Exception as e:
1284 self.logger.exception('perform-test-Error', e=e,
1285 class_id=self._entity_class,
1286 entity_id=self._entity_id)
1287 self.deferred.errback(failure.Failure(e))
1288
1289 */
1290
1291 // PM related heartbeat??? !!!TODO....
1292 //self._heartbeat.enabled = True
1293
mpagenko1cc3cb42020-07-27 15:24:38 +00001294 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1295 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1296 * 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 +05301297 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001298 */
1299 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001300 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001301 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001302 if pMibUlFsm.Is(ulStDisabled) {
1303 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001304 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001305 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301306 }
1307 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1308 //Determine ONU status and start/re-start MIB Synchronization tasks
1309 //Determine if this ONU has ever synchronized
1310 if true { //TODO: insert valid check
1311 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001312 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 +00001313 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001314 }
Himani Chawla4d908332020-08-31 12:30:20 +05301315 } else {
1316 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001317 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 +00001318 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301319 }
1320 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1321 //Examine the MIB Data Sync
1322 // callbacks to be handled:
1323 // Event(ulEvSuccess)
1324 // Event(ulEvTimeout)
1325 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001326 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001327 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001328 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001329 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001330 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001331 }
1332 } else {
divyadesai4d299552020-08-18 07:13:49 +00001333 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001334 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001335 }
1336 return nil
1337}
1338
Himani Chawla6d2ae152020-09-02 13:11:20 +05301339func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001340 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001341 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
mpagenko3af1f032020-06-10 08:53:41 +00001342 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001343 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001344
mpagenko900ee4b2020-10-12 11:56:34 +00001345 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1346 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1347 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1348 if err := dh.resetFsms(); err != nil {
1349 logger.Errorw("error-updateInterface at FSM stop",
1350 log.Fields{"device-id": dh.deviceID, "error": err})
1351 // abort: system behavior is just unstable ...
1352 return err
1353 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001354 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
mpagenko2418ab02020-11-12 12:58:06 +00001355 _ = dh.deleteDevicePersistencyData() //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001356
1357 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1358 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1359 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301360 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001361 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001362 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001363 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001364 }
mpagenko900ee4b2020-10-12 11:56:34 +00001365 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001366
1367 //TODO!!! remove existing traffic profiles
1368 /* from py code, if TP's exist, remove them - not yet implemented
1369 self._tp = dict()
1370 # Let TP download happen again
1371 for uni_id in self._tp_service_specific_task:
1372 self._tp_service_specific_task[uni_id].clear()
1373 for uni_id in self._tech_profile_download_done:
1374 self._tech_profile_download_done[uni_id].clear()
1375 */
1376
1377 dh.disableUniPortStateUpdate()
1378
mpagenkofc4f56e2020-11-04 17:17:49 +00001379 dh.deviceReason = "stopping-openomci"
1380 dh.ReadyForSpecificOmciConfig = false
1381
mpagenko3af1f032020-06-10 08:53:41 +00001382 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001383 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001384 logger.Errorw("error-DeviceReasonUpdate to stopping-openomci",
divyadesai4d299552020-08-18 07:13:49 +00001385 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001386 // abort: system behavior is just unstable ...
1387 return err
1388 }
mpagenko3af1f032020-06-10 08:53:41 +00001389
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001390 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1391 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001392 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1393 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001394 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001395 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001396 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001397 // abort: system behavior is just unstable ...
1398 return err
1399 }
1400 } else {
divyadesai4d299552020-08-18 07:13:49 +00001401 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001402 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001403 return nil
1404}
1405
mpagenko900ee4b2020-10-12 11:56:34 +00001406func (dh *deviceHandler) resetFsms() error {
1407 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1408 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1409 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1410 // and using the stop/reset event should never harm
1411
1412 pDevEntry := dh.getOnuDeviceEntry(false)
1413 if pDevEntry == nil {
1414 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1415 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1416 }
1417
1418 //the MibSync FSM might be active all the ONU-active time,
1419 // hence it must be stopped unconditionally
1420 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1421 if pMibUlFsm != nil {
1422 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1423 }
1424 //MibDownload may run
1425 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1426 if pMibDlFsm != nil {
1427 _ = pMibDlFsm.Event(dlEvReset)
1428 }
1429 //port lock/unlock FSM's may be active
1430 if dh.pUnlockStateFsm != nil {
1431 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1432 }
1433 if dh.pLockStateFsm != nil {
1434 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1435 }
1436 //techProfile related PonAniConfigFsm FSM may be active
1437 if dh.pOnuTP != nil {
1438 // should always be the case here
1439 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1440 if dh.pOnuTP.pAniConfigFsm != nil {
1441 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1442 }
1443 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001444 // reset the possibly existing VlanConfigFsm
1445 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1446 //VlanFilterFsm exists and was already started
1447 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1448 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001449 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001450 // no need to remove specific data
1451 pVlanFilterFsm.RequestClearPersistency(false)
1452 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001453 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1454 }
1455 }
1456 }
1457 }
1458 //TODO!!! care about PM/Alarm processing once started
1459 return nil
1460}
1461
Himani Chawla6d2ae152020-09-02 13:11:20 +05301462func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001463 logger.Debugw("MibInSync event received, adding uni ports and locking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301464 if !dh.reconciling {
1465 //initiate DevStateUpdate
1466 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1467 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001468 logger.Errorw("error-DeviceReasonUpdate to mibsync-complete", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301469 "device-id": dh.deviceID, "error": err})
1470 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001471 logger.Infow("dev reason updated to MibSync complete", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301472 }
1473 } else {
1474 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1475 log.Fields{"device-id": dh.deviceID})
1476 }
1477 //set internal state anyway - as it was done
1478 dh.deviceReason = "discovery-mibsync-complete"
1479
Himani Chawla6d2ae152020-09-02 13:11:20 +05301480 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenkoa40e99a2020-11-17 13:50:39 +00001481 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301482 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301483 for _, mgmtEntityID := range unigInstKeys {
1484 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1485 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301486 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301487 i++
1488 }
1489 } else {
1490 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1491 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301492 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301493 for _, mgmtEntityID := range veipInstKeys {
1494 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1495 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301496 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301497 i++
1498 }
1499 } else {
1500 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1501 }
1502 if i == 0 {
1503 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1504 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001505 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1506 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1507 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1508 * disable/enable toggling here to allow traffic
1509 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1510 * like the py comment says:
1511 * # start by locking all the unis till mib sync and initial mib is downloaded
1512 * # this way we can capture the port down/up events when we are ready
1513 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301514
mpagenkoa40e99a2020-11-17 13:50:39 +00001515 // Init Uni Ports to Admin locked state
1516 // *** should generate UniLockStateDone event *****
1517 if dh.pLockStateFsm == nil {
1518 dh.createUniLockFsm(true, UniLockStateDone)
1519 } else { //LockStateFSM already init
1520 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
1521 dh.runUniLockFsm(true)
1522 }
1523}
1524
1525func (dh *deviceHandler) processUniLockStateDoneEvent(devEvent OnuDeviceEvent) {
1526 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301527 /* Mib download procedure -
1528 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1529 */
mpagenkoa40e99a2020-11-17 13:50:39 +00001530 pDevEntry := dh.getOnuDeviceEntry(false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301531 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1532 if pMibDlFsm != nil {
1533 if pMibDlFsm.Is(dlStDisabled) {
1534 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001535 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301536 // maybe try a FSM reset and then again ... - TODO!!!
1537 } else {
1538 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1539 // maybe use more specific states here for the specific download steps ...
1540 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001541 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301542 } else {
1543 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1544 //Begin MIB data download (running autonomously)
1545 }
1546 }
1547 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001548 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001549 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301550 // maybe try a FSM reset and then again ... - TODO!!!
1551 }
1552 /***** Mib download started */
1553 } else {
1554 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1555 }
1556}
1557
Himani Chawla6d2ae152020-09-02 13:11:20 +05301558func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001559 logger.Debugw("MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301560 //initiate DevStateUpdate
1561 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001562 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1563 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301564 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1565 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1566 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1567 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1568 } else {
1569 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1570 }
1571 } else {
1572 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1573 log.Fields{"device-id": dh.deviceID})
1574 }
1575 if !dh.reconciling {
1576 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1577 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001578 logger.Errorw("error-DeviceReasonUpdate to initial-mib-downloaded",
Himani Chawla26e555c2020-08-31 12:30:20 +05301579 log.Fields{"device-id": dh.deviceID, "error": err})
1580 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001581 logger.Infow("dev reason updated to initial-mib-downloaded", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301582 }
1583 } else {
1584 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1585 log.Fields{"device-id": dh.deviceID})
1586 }
1587 //set internal state anyway - as it was done
1588 dh.deviceReason = "initial-mib-downloaded"
mpagenkofc4f56e2020-11-04 17:17:49 +00001589 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301590 // *** should generate UniUnlockStateDone event *****
1591 if dh.pUnlockStateFsm == nil {
1592 dh.createUniLockFsm(false, UniUnlockStateDone)
1593 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301594 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301595 dh.runUniLockFsm(false)
1596 }
1597}
1598
Himani Chawla6d2ae152020-09-02 13:11:20 +05301599func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001600 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301601
1602 if !dh.reconciling {
1603 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1604 raisedTs := time.Now().UnixNano()
1605 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1606 } else {
1607 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1608 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301609 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001610 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301611 }
1612}
1613
mpagenko900ee4b2020-10-12 11:56:34 +00001614func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1615 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1616 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1617 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1618 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1619 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1620 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1621 }
1622
mpagenkofc4f56e2020-11-04 17:17:49 +00001623 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{
mpagenko900ee4b2020-10-12 11:56:34 +00001624 "reason": "omci-admin-lock", "device-id": dh.deviceID})
1625 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1626 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
1627 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1628 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1629 }
1630 dh.deviceReason = "omci-admin-lock"
1631
1632 //transfer the modified logical uni port state
1633 dh.disableUniPortStateUpdate()
mpagenko900ee4b2020-10-12 11:56:34 +00001634}
1635
1636func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1637 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1638 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1639 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1640 voltha.OperStatus_ACTIVE); err != nil {
1641 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1642 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1643 }
1644
1645 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1646 "reason": "onu-reenabled", "device-id": dh.deviceID})
1647 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1648 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
1649 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1650 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1651 }
1652 dh.deviceReason = "onu-reenabled"
1653
1654 //transfer the modified logical uni port state
1655 dh.enableUniPortStateUpdate()
1656}
1657
Himani Chawla6d2ae152020-09-02 13:11:20 +05301658func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001659 if devEvent == OmciAniConfigDone {
1660 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1661 // attention: the device reason update is done based on ONU-UNI-Port related activity
1662 // - which may cause some inconsistency
1663 if dh.deviceReason != "tech-profile-config-download-success" {
1664 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
1665 if !dh.reconciling {
1666 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1667 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1668 logger.Errorw("error-DeviceReasonUpdate to tech-profile-config-download-success",
1669 log.Fields{"device-id": dh.deviceID, "error": err})
1670 } else {
1671 logger.Infow("update dev reason to tech-profile-config-download-success",
1672 log.Fields{"device-id": dh.deviceID})
1673 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301674 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001675 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
Himani Chawla26e555c2020-08-31 12:30:20 +05301676 log.Fields{"device-id": dh.deviceID})
1677 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001678 //set internal state anyway - as it was done
1679 dh.deviceReason = "tech-profile-config-download-success"
Himani Chawla26e555c2020-08-31 12:30:20 +05301680 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001681 if dh.reconciling {
1682 go dh.reconcileDeviceFlowConfig()
1683 }
1684 } else { // should be the OmciAniResourceRemoved block
1685 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1686 // attention: the device reason update is done based on ONU-UNI-Port related activity
1687 // - which may cause some inconsistency
1688 if dh.deviceReason != "tech-profile-config-delete-success" {
1689 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
1690 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-delete-success"); err != nil {
1691 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1692 logger.Errorw("error-DeviceReasonUpdate to tech-profile-config-delete-success",
1693 log.Fields{"device-id": dh.deviceID, "error": err})
1694 } else {
1695 logger.Infow("update dev reason to tech-profile-config-delete-success",
1696 log.Fields{"device-id": dh.deviceID})
1697 }
1698 //set internal state anyway - as it was done
1699 dh.deviceReason = "tech-profile-config-delete-success"
1700 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001701 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301702}
1703
mpagenkofc4f56e2020-11-04 17:17:49 +00001704func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301705 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001706 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301707 // attention: the device reason update is done based on ONU-UNI-Port related activity
1708 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301709
mpagenkofc4f56e2020-11-04 17:17:49 +00001710 if aDevEvent == OmciVlanFilterAddDone {
1711 if dh.deviceReason != "omci-flows-pushed" {
1712 // which may be the case from some previous actvity on another UNI Port of the ONU
1713 // or even some previous flow add activity on the same port
1714 if !dh.reconciling {
1715 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1716 logger.Errorw("error-DeviceReasonUpdate to omci-flows-pushed",
1717 log.Fields{"device-id": dh.deviceID, "error": err})
1718 } else {
1719 logger.Infow("updated dev reason to omci-flows-pushed",
1720 log.Fields{"device-id": dh.deviceID})
1721 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001722 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001723 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001724 log.Fields{"device-id": dh.deviceID})
1725 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001726 //set internal state anyway - as it was done
1727 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001728
mpagenkofc4f56e2020-11-04 17:17:49 +00001729 if dh.reconciling {
1730 go dh.reconcileMetrics()
1731 }
1732 }
1733 } else {
1734 if dh.deviceReason != "omci-flows-deleted" {
1735 //not relevant for reconcile
1736 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-deleted"); err != nil {
1737 logger.Errorw("error-DeviceReasonUpdate to omci-flows-deleted",
1738 log.Fields{"device-id": dh.deviceID, "error": err})
1739 } else {
1740 logger.Infow("updated dev reason to omci-flows-deleted",
1741 log.Fields{"device-id": dh.deviceID})
1742 }
1743 //set internal state anyway - as it was done
1744 dh.deviceReason = "omci-flows-deleted"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001745 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301746 }
1747}
1748
Himani Chawla6d2ae152020-09-02 13:11:20 +05301749//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1750func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301751 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001752 case MibDatabaseSync:
1753 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301754 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001755 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001756 case UniLockStateDone:
1757 {
1758 dh.processUniLockStateDoneEvent(devEvent)
1759 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001760 case MibDownloadDone:
1761 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301762 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001763 }
1764 case UniUnlockStateDone:
1765 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301766 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001767 }
mpagenko900ee4b2020-10-12 11:56:34 +00001768 case UniEnableStateDone:
1769 {
1770 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001771 }
1772 case UniDisableStateDone:
1773 {
1774 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001775 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001776 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001777 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301778 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001779 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001780 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001781 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301782 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001783 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001784 default:
1785 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001786 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001787 }
1788 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789}
1790
Himani Chawla6d2ae152020-09-02 13:11:20 +05301791func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001792 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301793 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301794 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001795 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301796 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001797 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301798 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301799 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301801 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001803 //store UniPort with the System-PortNumber key
1804 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001805 if !dh.reconciling {
1806 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301807 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001808 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1809 } //error logging already within UniPort method
1810 } else {
1811 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1812 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001813 }
1814 }
1815}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001816
mpagenko3af1f032020-06-10 08:53:41 +00001817// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301818func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001819 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301820 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001821 // with following remark:
1822 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1823 // # load on the core
1824
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001825 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001826
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001827 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001828 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301829 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001830 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301831 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001832 if !dh.reconciling {
1833 //maybe also use getter functions on uniPort - perhaps later ...
1834 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1835 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001836 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001837 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1838 }
mpagenko3af1f032020-06-10 08:53:41 +00001839 }
1840 }
1841}
1842
1843// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301844func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001845 // compare enableUniPortStateUpdate() above
1846 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1847 for uniNo, uniPort := range dh.uniEntityMap {
1848 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301849 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001850 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301851 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001852 //maybe also use getter functions on uniPort - perhaps later ...
1853 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001854 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001855 }
1856}
1857
1858// ONU_Active/Inactive announcement on system KAFKA bus
1859// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301860func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001861 var de voltha.DeviceEvent
1862 eventContext := make(map[string]string)
1863 //Populating event context
1864 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301865 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001866 if err != nil || parentDevice == nil {
1867 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301868 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001869 }
1870 oltSerialNumber := parentDevice.SerialNumber
1871
1872 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1873 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1874 eventContext["serial-number"] = dh.device.SerialNumber
1875 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301876 eventContext["device_id"] = aDeviceID
1877 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001878 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001879 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001880
1881 /* Populating device event body */
1882 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301883 de.ResourceId = aDeviceID
1884 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001885 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1886 de.Description = fmt.Sprintf("%s Event - %s - %s",
1887 cEventObjectType, cOnuActivatedEvent, "Raised")
1888 } else {
1889 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1890 de.Description = fmt.Sprintf("%s Event - %s - %s",
1891 cEventObjectType, cOnuActivatedEvent, "Cleared")
1892 }
1893 /* Send event to KAFKA */
1894 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1895 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301896 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001897 }
1898 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301899 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001900}
1901
Himani Chawla4d908332020-08-31 12:30:20 +05301902// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301903func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001904 chLSFsm := make(chan Message, 2048)
1905 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301906 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001907 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001908 sFsmName = "LockStateFSM"
1909 } else {
divyadesai4d299552020-08-18 07:13:49 +00001910 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001911 sFsmName = "UnLockStateFSM"
1912 }
mpagenko3af1f032020-06-10 08:53:41 +00001913
Himani Chawla6d2ae152020-09-02 13:11:20 +05301914 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001915 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001916 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001917 return
1918 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301919 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001920 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001921 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301922 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001923 dh.pLockStateFsm = pLSFsm
1924 } else {
1925 dh.pUnlockStateFsm = pLSFsm
1926 }
1927 dh.runUniLockFsm(aAdminState)
1928 } else {
divyadesai4d299552020-08-18 07:13:49 +00001929 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001930 }
1931}
1932
1933// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301934func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001935 /* Uni Port lock/unlock procedure -
1936 ***** should run via 'adminDone' state and generate the argument requested event *****
1937 */
1938 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301939 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001940 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1941 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1942 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001943 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301944 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001945 }
1946 } else {
1947 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1948 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1949 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001950 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301951 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001952 }
1953 }
1954 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001955 if pLSStatemachine.Is(uniStDisabled) {
1956 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001957 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1958 // maybe try a FSM reset and then again ... - TODO!!!
1959 } else {
1960 /***** LockStateFSM started */
1961 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001962 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001963 }
1964 } else {
1965 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001966 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001967 // maybe try a FSM reset and then again ... - TODO!!!
1968 }
1969 } else {
divyadesai4d299552020-08-18 07:13:49 +00001970 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001971 // maybe try a FSM reset and then again ... - TODO!!!
1972 }
1973}
1974
Himani Chawla6d2ae152020-09-02 13:11:20 +05301975//setBackend provides a DB backend for the specified path on the existing KV client
1976func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001977 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1978 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001979 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001980 kvbackend := &db.Backend{
1981 Client: dh.pOpenOnuAc.kvClient,
1982 StoreType: dh.pOpenOnuAc.KVStoreType,
1983 /* address config update acc. to [VOL-2736] */
1984 Address: addr,
1985 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1986 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001987
mpagenkoaf801632020-07-03 10:00:42 +00001988 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001989}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301990func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301991 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001992
mpagenkodff5dda2020-08-28 11:52:01 +00001993 for _, field := range flow.GetOfbFields(apFlowItem) {
1994 switch field.Type {
1995 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1996 {
mpagenko01e726e2020-10-23 09:45:29 +00001997 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001998 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1999 }
mpagenko01e726e2020-10-23 09:45:29 +00002000 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002001 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2002 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302003 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002004 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302005 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2006 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002007 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2008 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002009 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2010 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302011 return
mpagenkodff5dda2020-08-28 11:52:01 +00002012 }
2013 }
mpagenko01e726e2020-10-23 09:45:29 +00002014 */
mpagenkodff5dda2020-08-28 11:52:01 +00002015 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2016 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302017 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002018 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302019 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002020 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302021 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002022 }
mpagenko01e726e2020-10-23 09:45:29 +00002023 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302024 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002025 }
2026 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2027 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302028 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002029 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002030 "PCP": loAddPcp})
2031 }
2032 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2033 {
mpagenko01e726e2020-10-23 09:45:29 +00002034 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002035 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2036 }
2037 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2038 {
mpagenko01e726e2020-10-23 09:45:29 +00002039 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002040 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2041 }
2042 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2043 {
mpagenko01e726e2020-10-23 09:45:29 +00002044 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002045 "IPv4-DST": field.GetIpv4Dst()})
2046 }
2047 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2048 {
mpagenko01e726e2020-10-23 09:45:29 +00002049 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002050 "IPv4-SRC": field.GetIpv4Src()})
2051 }
2052 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2053 {
mpagenko01e726e2020-10-23 09:45:29 +00002054 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002055 "Metadata": field.GetTableMetadata()})
2056 }
2057 /*
2058 default:
2059 {
2060 //all other entires ignored
2061 }
2062 */
2063 }
2064 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302065}
mpagenkodff5dda2020-08-28 11:52:01 +00002066
Himani Chawla6d2ae152020-09-02 13:11:20 +05302067func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002068 for _, action := range flow.GetActions(apFlowItem) {
2069 switch action.Type {
2070 /* not used:
2071 case of.OfpActionType_OFPAT_OUTPUT:
2072 {
mpagenko01e726e2020-10-23 09:45:29 +00002073 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002074 "Output": action.GetOutput()})
2075 }
2076 */
2077 case of.OfpActionType_OFPAT_PUSH_VLAN:
2078 {
mpagenko01e726e2020-10-23 09:45:29 +00002079 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002080 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2081 }
2082 case of.OfpActionType_OFPAT_SET_FIELD:
2083 {
2084 pActionSetField := action.GetSetField()
2085 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00002086 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002087 "OxcmClass": pActionSetField.Field.OxmClass})
2088 }
2089 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302090 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002091 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302092 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002093 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302094 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002095 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302096 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002097 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002098 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002099 "Type": pActionSetField.Field.GetOfbField().Type})
2100 }
2101 }
2102 /*
2103 default:
2104 {
2105 //all other entires ignored
2106 }
2107 */
2108 }
2109 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302110}
2111
2112//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302113func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302114 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2115 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2116 var loAddPcp, loSetPcp uint8
2117 var loIPProto uint32
2118 /* the TechProfileId is part of the flow Metadata - compare also comment within
2119 * OLT-Adapter:openolt_flowmgr.go
2120 * Metadata 8 bytes:
2121 * Most Significant 2 Bytes = Inner VLAN
2122 * Next 2 Bytes = Tech Profile ID(TPID)
2123 * Least Significant 4 Bytes = Port ID
2124 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2125 * subscriber related flows.
2126 */
2127
2128 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2129 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002130 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302131 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002132 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302133 }
2134 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002135 loCookie := apFlowItem.GetCookie()
2136 loCookieSlice := []uint64{loCookie}
2137 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2138 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302139
2140 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002141 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 if loIPProto == 2 {
2143 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2144 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002145 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2146 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302147 return nil
2148 }
mpagenko01e726e2020-10-23 09:45:29 +00002149 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302150 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002151
2152 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002153 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002154 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2155 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2156 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2157 //TODO!!: Use DeviceId within the error response to rwCore
2158 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002159 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002160 }
2161 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002162 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002163 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2164 } else {
2165 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2166 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2167 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302168 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002169 }
mpagenko01e726e2020-10-23 09:45:29 +00002170 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002171 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302172 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002173 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2174 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002175 }
mpagenko01e726e2020-10-23 09:45:29 +00002176 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002177 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002178}
2179
2180//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2181func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2182 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2183 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2184 //no extra check is done on the rule parameters
2185 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2186 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2187 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2188 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002189 // - 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 +00002190 loCookie := apFlowItem.GetCookie()
2191 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2192
2193 /* TT related temporary workaround - should not be needed anymore
2194 for _, field := range flow.GetOfbFields(apFlowItem) {
2195 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2196 loIPProto := field.GetIpProto()
2197 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2198 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2199 if loIPProto == 2 {
2200 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2201 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2202 log.Fields{"device-id": dh.deviceID})
2203 return nil
2204 }
2205 }
2206 } //for all OfbFields
2207 */
2208
2209 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2210 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2211 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002212 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002213 log.Fields{"device-id": dh.deviceID})
2214 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002215 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2216 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2217
mpagenko01e726e2020-10-23 09:45:29 +00002218 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002219}
2220
Himani Chawla26e555c2020-08-31 12:30:20 +05302221// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002222func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2223 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002224 chVlanFilterFsm := make(chan Message, 2048)
2225
Himani Chawla6d2ae152020-09-02 13:11:20 +05302226 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002227 if pDevEntry == nil {
2228 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302229 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002230 }
2231
2232 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002233 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2234 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002235 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302236 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002237 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2238 if pVlanFilterStatemachine != nil {
2239 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2240 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2241 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302242 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002243 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302244 /***** UniVlanConfigFsm started */
2245 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2246 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2247 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002248 } else {
2249 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2250 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302251 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002252 }
2253 } else {
2254 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2255 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302256 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002257 }
2258 } else {
2259 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2260 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302261 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002262 }
2263 return nil
2264}
2265
mpagenkofc4f56e2020-11-04 17:17:49 +00002266//VerifyVlanConfigRequest checks on existence of a given uniPort
2267// and starts verification of flow config based on that
2268func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2269 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2270 var pCurrentUniPort *onuUniPort
2271 for _, uniPort := range dh.uniEntityMap {
2272 // only if this port is validated for operState transfer
2273 if uniPort.uniID == uint8(aUniID) {
2274 pCurrentUniPort = uniPort
2275 break //found - end search loop
2276 }
2277 }
2278 if pCurrentUniPort == nil {
2279 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2280 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2281 return
2282 }
2283 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2284}
2285
mpagenkodff5dda2020-08-28 11:52:01 +00002286//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302287func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002288 //TODO!! verify and start pending flow configuration
2289 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2290 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302291 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002292 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2293 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2294 if pVlanFilterStatemachine != nil {
2295 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2296 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2297 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2298 } else {
2299 /***** UniVlanConfigFsm continued */
2300 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2301 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2302 "UniPort": apUniPort.portNo})
2303 }
2304 } else {
2305 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2306 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2307 }
2308 } else {
2309 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2310 "device-id": dh.deviceID})
2311 }
2312
2313 } // else: nothing to do
2314}
2315
2316//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2317// 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 +05302318func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002319 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2320 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2321 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302322 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002323}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002324
2325//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2326//available for potential reconcilement
2327
2328func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2329
2330 if dh.reconciling {
2331 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2332 return nil
2333 }
mpagenko2418ab02020-11-12 12:58:06 +00002334 logger.Debugw("Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002335
2336 pDevEntry := dh.getOnuDeviceEntry(true)
2337 if pDevEntry == nil {
2338 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2339 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2340 }
2341 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2342
2343 pDevEntry.lockOnuKVStoreMutex()
2344 defer pDevEntry.unlockOnuKVStoreMutex()
2345
2346 // deadline context to ensure completion of background routines waited for
2347 //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 +05302348 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002349 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2350
2351 pDevEntry.resetKvProcessingErrorIndication()
2352 var wg sync.WaitGroup
2353 wg.Add(1) // for the 1 go routine to finish
2354
2355 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002356 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002357
2358 return pDevEntry.getKvProcessingErrorIndication()
2359}
2360
mpagenko01e726e2020-10-23 09:45:29 +00002361func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002362 defer cancel() //ensure termination of context (may be pro forma)
2363 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002364 logger.Debugw("WaitGroup processing completed", log.Fields{
2365 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002366}
2367
2368func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2369 var errStr string = ""
2370 for _, err := range errS {
2371 if err != nil {
2372 errStr = errStr + err.Error() + " "
2373 }
2374 }
2375 if errStr != "" {
2376 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2377 }
2378 return nil
2379}