blob: 3f530504a56c0aa354ac24d3696303b85742deb6 [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)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800319 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
320 if err != nil {
321 logger.Errorw("error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
322 return err
323 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000324
Girish Gowdra041dcb32020-11-16 16:54:30 -0800325 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530326 // if there has been some change for some uni TechProfilePath
327 //in order to allow concurrent calls to other dh instances we do not wait for execution here
328 //but doing so we can not indicate problems to the caller (who does what with that then?)
329 //by now we just assume straightforward successful execution
330 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
331 // possible problems to the caller later autonomously
332
333 // deadline context to ensure completion of background routines waited for
334 //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 +0530335 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 dctx, cancel := context.WithDeadline(context.Background(), deadline)
337
Girish Gowdra041dcb32020-11-16 16:54:30 -0800338 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000339 pDevEntry.resetKvProcessingErrorIndication()
340
Himani Chawla26e555c2020-08-31 12:30:20 +0530341 var wg sync.WaitGroup
342 wg.Add(2) // for the 2 go routines to finish
343 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000344 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
345 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000346 dh.waitForCompletion(cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000347
Girish Gowdra041dcb32020-11-16 16:54:30 -0800348 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000350 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 return nil
352}
353
Himani Chawla6d2ae152020-09-02 13:11:20 +0530354func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 msg *ic.InterAdapterMessage) error {
356
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000357 pDevEntry := dh.getOnuDeviceEntry(true)
358 if pDevEntry == nil {
359 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
360 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
361 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 if dh.pOnuTP == nil {
363 //should normally not happen ...
364 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
365 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 }
368
369 msgBody := msg.GetBody()
370 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
371 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
372 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
373 "device-id": dh.deviceID, "error": err})
374 return err
375 }
376
377 //compare TECH_PROFILE_DOWNLOAD_REQUEST
378 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 defer dh.pOnuTP.unlockTpProcMutex()
380 pDevEntry.lockOnuKVStoreMutex()
381 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530382
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000383 if delGemPortMsg.UniId > 255 {
384 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
385 delGemPortMsg.UniId, dh.deviceID))
386 }
387 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800388 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
389 if err != nil {
390 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
391 return err
392 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530393
mpagenkofc4f56e2020-11-04 17:17:49 +0000394 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395
mpagenkofc4f56e2020-11-04 17:17:49 +0000396 // deadline context to ensure completion of background routines waited for
397 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
398 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399
Girish Gowdra041dcb32020-11-16 16:54:30 -0800400 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
mpagenkofc4f56e2020-11-04 17:17:49 +0000402 var wg sync.WaitGroup
403 wg.Add(1) // for the 1 go routine to finish
404 go dh.pOnuTP.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
405 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
406 dh.waitForCompletion(cancel, &wg, "GemDelete") //wait for background process to finish
407
Girish Gowdra041dcb32020-11-16 16:54:30 -0800408 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530409}
410
Himani Chawla6d2ae152020-09-02 13:11:20 +0530411func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
414 pDevEntry := dh.getOnuDeviceEntry(true)
415 if pDevEntry == nil {
416 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
417 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
418 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 if dh.pOnuTP == nil {
420 //should normally not happen ...
421 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
422 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 }
425
426 msgBody := msg.GetBody()
427 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
428 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
429 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
430 "device-id": dh.deviceID, "error": err})
431 return err
432 }
433
434 //compare TECH_PROFILE_DOWNLOAD_REQUEST
435 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 defer dh.pOnuTP.unlockTpProcMutex()
437 pDevEntry.lockOnuKVStoreMutex()
438 defer pDevEntry.unlockOnuKVStoreMutex()
439
440 if delTcontMsg.UniId > 255 {
441 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
442 delTcontMsg.UniId, dh.deviceID))
443 }
444 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800445 tpPath := delTcontMsg.TpPath
446 tpID, err := GetTpIDFromTpPath(tpPath)
447 if err != nil {
448 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
449 return err
450 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000451
Girish Gowdra041dcb32020-11-16 16:54:30 -0800452 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530454 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 dctx, cancel := context.WithDeadline(context.Background(), deadline)
456
Girish Gowdra041dcb32020-11-16 16:54:30 -0800457 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000458 pDevEntry.resetKvProcessingErrorIndication()
459
Himani Chawla26e555c2020-08-31 12:30:20 +0530460 var wg sync.WaitGroup
461 wg.Add(2) // for the 2 go routines to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000462 go dh.pOnuTP.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530463 cResourceTcont, delTcontMsg.AllocId, &wg)
464 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000465 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000466 dh.waitForCompletion(cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467
Girish Gowdra041dcb32020-11-16 16:54:30 -0800468 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 return nil
471}
472
Himani Chawla6d2ae152020-09-02 13:11:20 +0530473//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000474// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
475// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530476func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000477 msgID := msg.Header.Id
478 msgType := msg.Header.Type
479 fromTopic := msg.Header.FromTopic
480 toTopic := msg.Header.ToTopic
481 toDeviceID := msg.Header.ToDeviceId
482 proxyDeviceID := msg.Header.ProxyDeviceId
483 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
484 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
485
486 switch msgType {
487 case ic.InterAdapterMessageType_OMCI_REQUEST:
488 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000490 }
491 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
492 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000494 }
mpagenkoaf801632020-07-03 10:00:42 +0000495 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
496 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530497 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000498 }
499 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
500 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000502
mpagenkoaf801632020-07-03 10:00:42 +0000503 }
504 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
505 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530506 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000507 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000508 default:
509 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000510 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511 "msgType": msg.Header.Type, "device-id": dh.deviceID})
512 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000513 }
514 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000515}
516
mpagenkodff5dda2020-08-28 11:52:01 +0000517//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530518func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000519 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
mpagenko01e726e2020-10-23 09:45:29 +0000520 logger.Debugw("FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000521
mpagenko01e726e2020-10-23 09:45:29 +0000522 var retError error = nil
523 //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 +0000524 if apOfFlowChanges.ToRemove != nil {
525 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000526 if flowItem.GetCookie() == 0 {
mpagenko01e726e2020-10-23 09:45:29 +0000527 logger.Warnw("flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
528 "device-id": dh.deviceID})
529 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000530 continue
531 }
532 flowInPort := flow.GetInPort(flowItem)
533 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
mpagenko01e726e2020-10-23 09:45:29 +0000534 logger.Warnw("flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
535 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
536 continue
537 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000538 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000539 //this is some downstream flow, not regarded as error, just ignored
540 logger.Debugw("flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
541 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000542 continue
543 } else {
544 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530545 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000546 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
547 loUniPort = uniPort
548 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000549 logger.Warnw("flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
550 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
551 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
552 flowInPort, dh.deviceID)
553 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000554 }
555 flowOutPort := flow.GetOutPort(flowItem)
mpagenko01e726e2020-10-23 09:45:29 +0000556 logger.Debugw("flow-remove port indications", log.Fields{
557 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000558 "uniPortName": loUniPort.name})
mpagenko01e726e2020-10-23 09:45:29 +0000559 err := dh.removeFlowItemFromUniPort(flowItem, loUniPort)
560 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000561 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000562 logger.Warnw("flow-remove processing error: continuing on checking further flows",
563 log.Fields{"device-id": dh.deviceID, "error": err})
564 retError = err
565 continue
566 //return err
567 } else { // if last setting succeeds, overwrite possibly previously set error
568 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000569 }
570 }
571 }
572 }
mpagenko01e726e2020-10-23 09:45:29 +0000573 if apOfFlowChanges.ToAdd != nil {
574 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
575 if flowItem.GetCookie() == 0 {
576 logger.Debugw("incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
577 "device-id": dh.deviceID})
578 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
579 continue
580 }
581 flowInPort := flow.GetInPort(flowItem)
582 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
583 logger.Warnw("flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
584 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
585 continue
586 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
587 } else if flowInPort == dh.ponPortNumber {
588 //this is some downstream flow
589 logger.Debugw("flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
590 "device-id": dh.deviceID, "inPort": flowInPort})
591 continue
592 } else {
593 // this is the relevant upstream flow
594 var loUniPort *onuUniPort
595 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
596 loUniPort = uniPort
597 } else {
598 logger.Warnw("flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
599 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
600 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
601 flowInPort, dh.deviceID)
602 continue
603 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
604 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000605 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
606 // if not, we just throw some error here to have an indication about that, if we really need to support that
607 // then we would need to create some means to activate the internal stored flows
608 // after the device gets active automatically (and still with its dependency to the TechProfile)
609 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
610 // also abort for the other still possible flows here
611 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000612 logger.Errorw("flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
mpagenkofc4f56e2020-11-04 17:17:49 +0000613 "last device-reason": dh.deviceReason})
614 return fmt.Errorf("improper device state on device %s", dh.deviceID)
615 }
616
mpagenko01e726e2020-10-23 09:45:29 +0000617 flowOutPort := flow.GetOutPort(flowItem)
618 logger.Debugw("flow-add port indications", log.Fields{
619 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
620 "uniPortName": loUniPort.name})
621 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
622 //try next flow after processing error
623 if err != nil {
624 logger.Warnw("flow-add processing error: continuing on checking further flows",
625 log.Fields{"device-id": dh.deviceID, "error": err})
626 retError = err
627 continue
628 //return err
629 } else { // if last setting succeeds, overwrite possibly previously set error
630 retError = nil
631 }
632 }
633 }
634 }
635 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000636}
637
Himani Chawla6d2ae152020-09-02 13:11:20 +0530638//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000639//following are the expected device states after this activity:
640//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
641// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530642func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000643 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000644
mpagenko900ee4b2020-10-12 11:56:34 +0000645 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000646 //note that disableDevice sequences in some 'ONU active' state may yield also
647 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000648 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
mpagenko3af1f032020-06-10 08:53:41 +0000649 if dh.deviceReason != "omci-admin-lock" {
mpagenkofc4f56e2020-11-04 17:17:49 +0000650 //disable-device shall be just a UNi/ONU-G related admin state setting
651 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000652
mpagenkofc4f56e2020-11-04 17:17:49 +0000653 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000654 // disable UNI ports/ONU
655 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
656 if dh.pLockStateFsm == nil {
657 dh.createUniLockFsm(true, UniDisableStateDone)
658 } else { //LockStateFSM already init
659 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
660 dh.runUniLockFsm(true)
661 }
662 } else {
663 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
664 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
665 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
666 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
667 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
668 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
669 }
670
mpagenko2418ab02020-11-12 12:58:06 +0000671 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000672 "reason": "omci-admin-lock", "device-id": dh.deviceID})
673 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
674 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
675 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
676 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
677 }
678 dh.deviceReason = "omci-admin-lock"
mpagenko3af1f032020-06-10 08:53:41 +0000679 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300680 }
681}
682
Himani Chawla6d2ae152020-09-02 13:11:20 +0530683//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530684func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000685 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000686
mpagenkofc4f56e2020-11-04 17:17:49 +0000687 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
688 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
689 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
690 // for real ONU's that should have nearly no influence
691 // Note that for real ONU's there is anyway a problematic situation with following sequence:
692 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
693 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
694 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
695 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
696
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000697 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000698 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000699 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000700 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000701 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000702 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000703 dh.runUniLockFsm(false)
704 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300705}
706
Himani Chawla6d2ae152020-09-02 13:11:20 +0530707func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000708 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
709
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000710 pDevEntry := dh.getOnuDeviceEntry(true)
711 if pDevEntry == nil {
712 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
713 return
714 }
715 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000716 if err == fmt.Errorf("no-ONU-data-found") {
717 logger.Debugw("no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
718 } else {
719 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
720 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000721 dh.reconciling = false
722 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000723 }
Himani Chawla4d908332020-08-31 12:30:20 +0530724 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000725 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
726 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
727 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
728 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530729 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000730}
731
Himani Chawla6d2ae152020-09-02 13:11:20 +0530732func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000733 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
734
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000735 pDevEntry := dh.getOnuDeviceEntry(true)
736 if pDevEntry == nil {
737 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
738 return
739 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000740
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000741 dh.pOnuTP.lockTpProcMutex()
742 defer dh.pOnuTP.unlockTpProcMutex()
743
744 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800745 for tpID := range uniData.PersTpPathMap {
746 // deadline context to ensure completion of background routines waited for
747 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
748 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
749 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000750
Girish Gowdra041dcb32020-11-16 16:54:30 -0800751 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
752 var wg sync.WaitGroup
753 wg.Add(1) // for the 1 go routine to finish
754 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
755 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
756 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
757 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
758 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000759 }
760 }
761}
762
763func (dh *deviceHandler) reconcileDeviceFlowConfig() {
764 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
765
766 pDevEntry := dh.getOnuDeviceEntry(true)
767 if pDevEntry == nil {
768 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000769 return
770 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000771 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
772 var uniPort *onuUniPort
773 var exist bool
774 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
775 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000776 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000777 return
778 }
779 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000780 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
781 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000782 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000783 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
784 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
785 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000786 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
787 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000788 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000789 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
790 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000791 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
793 }
794 }
795 }
796 }
797}
798
799func (dh *deviceHandler) reconcileMetrics() {
800 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
801
802 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000803 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000804}
805
mpagenko2418ab02020-11-12 12:58:06 +0000806func (dh *deviceHandler) deleteDevicePersistencyData() error {
807 logger.Debugw("delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808
mpagenko2418ab02020-11-12 12:58:06 +0000809 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000810 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000811 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
812 logger.Debugw("OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
813 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000814 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000815 pDevEntry.lockOnuKVStoreMutex()
816 defer pDevEntry.unlockOnuKVStoreMutex()
817
818 // deadline context to ensure completion of background routines waited for
819 //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 +0530820 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000821 dctx, cancel := context.WithDeadline(context.Background(), deadline)
822
823 pDevEntry.resetKvProcessingErrorIndication()
824
825 var wg sync.WaitGroup
826 wg.Add(1) // for the 1 go routine to finish
827 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000828 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000829
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000830 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000832}
833
Himani Chawla6d2ae152020-09-02 13:11:20 +0530834func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000835 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300836 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000837 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300839 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530840 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530841 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
842 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
843 return err
844 }
mpagenko01e726e2020-10-23 09:45:29 +0000845
846 //transfer the possibly modified logical uni port state
847 dh.disableUniPortStateUpdate()
848
Andrea Campanellabef4e542020-10-22 11:01:28 +0200849 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000850 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200851 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300852 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000853 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000854 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300855 return err
856 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200857 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000858 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000859 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300860 return err
861 }
mpagenko01e726e2020-10-23 09:45:29 +0000862 dh.deviceReason = "rebooting"
mpagenkofc4f56e2020-11-04 17:17:49 +0000863 dh.ReadyForSpecificOmciConfig = false
ozgecanetsiae11479f2020-07-06 09:44:47 +0300864 return nil
865}
866
Himani Chawla6d2ae152020-09-02 13:11:20 +0530867// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000868// #####################################################################################
869
870// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530871// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000872
Himani Chawla6d2ae152020-09-02 13:11:20 +0530873func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000874 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})
875}
876
877// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530878func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000879
880 logger.Debug("doStateInit-started")
881 var err error
882
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000883 // populate what we know. rest comes later after mib sync
884 dh.device.Root = false
885 dh.device.Vendor = "OpenONU"
886 dh.device.Model = "go"
887 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000888 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000889
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000890 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000891
892 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530893 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000894 } else {
895 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
896 log.Fields{"device-id": dh.deviceID})
897 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000898
Himani Chawla4d908332020-08-31 12:30:20 +0530899 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000900 dh.ponPortNumber = dh.device.ParentPortNo
901
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000902 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
903 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
904 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000905 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000906 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530907 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000908
909 /*
910 self._pon = PonPort.create(self, self._pon_port_number)
911 self._pon.add_peer(self.parent_id, self._pon_port_number)
912 self.logger.debug('adding-pon-port-to-agent',
913 type=self._pon.get_port().type,
914 admin_state=self._pon.get_port().admin_state,
915 oper_status=self._pon.get_port().oper_status,
916 )
917 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000918 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000919 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000920 var ponPortNo uint32 = 1
921 if dh.ponPortNumber != 0 {
922 ponPortNo = dh.ponPortNumber
923 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000924
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000925 pPonPort := &voltha.Port{
926 PortNo: ponPortNo,
927 Label: fmt.Sprintf("pon-%d", ponPortNo),
928 Type: voltha.Port_PON_ONU,
929 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530930 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000931 PortNo: ponPortNo}}, // Peer port is parent's port number
932 }
933 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
934 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
935 e.Cancel(err)
936 return
937 }
938 } else {
939 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000940 }
941 logger.Debug("doStateInit-done")
942}
943
944// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530945func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000946
947 logger.Debug("postInit-started")
948 var err error
949 /*
950 dh.Client = oop.NewOpenoltClient(dh.clientCon)
951 dh.pTransitionMap.Handle(ctx, GrpcConnected)
952 return nil
953 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530954 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
955 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000956 e.Cancel(err)
957 return
958 }
959
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000960 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530961 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000962 // reconcilement will be continued after mib download is done
963 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000964 /*
965 ############################################################################
966 # Setup Alarm handler
967 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
968 device.serial_number)
969 ############################################################################
970 # Setup PM configuration for this device
971 # Pass in ONU specific options
972 kwargs = {
973 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
974 'heartbeat': self.heartbeat,
975 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
976 }
977 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
978 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
979 self.logical_device_id, device.serial_number,
980 grouped=True, freq_override=False, **kwargs)
981 pm_config = self._pm_metrics.make_proto()
982 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
983 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
984 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
985
986 # Note, ONU ID and UNI intf set in add_uni_port method
987 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
988 ani_ports=[self._pon])
989
990 # Code to Run OMCI Test Action
991 kwargs_omci_test_action = {
992 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
993 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
994 }
995 serial_number = device.serial_number
996 self._test_request = OmciTestRequest(self.core_proxy,
997 self.omci_agent, self.device_id,
998 AniG, serial_number,
999 self.logical_device_id,
1000 exclusive=False,
1001 **kwargs_omci_test_action)
1002
1003 self.enabled = True
1004 else:
1005 self.logger.info('onu-already-activated')
1006 */
1007 logger.Debug("postInit-done")
1008}
1009
1010// doStateConnected get the device info and update to voltha core
1011// for comparison of the original method (not that easy to uncomment): compare here:
1012// voltha-openolt-adapter/adaptercore/device_handler.go
1013// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +05301014func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001015
1016 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301017 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001018 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001019 logger.Debug("doStateConnected-done")
1020}
1021
1022// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301023func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001024
1025 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301026 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001027 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001028 logger.Debug("doStateUp-done")
1029
1030 /*
1031 // Synchronous call to update device state - this method is run in its own go routine
1032 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1033 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001034 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 +00001035 return err
1036 }
1037 return nil
1038 */
1039}
1040
1041// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301042func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001043
1044 logger.Debug("doStateDown-started")
1045 var err error
1046
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001047 device := dh.device
1048 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001049 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001050 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001051 e.Cancel(err)
1052 return
1053 }
1054
1055 cloned := proto.Clone(device).(*voltha.Device)
1056 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1057 /*
1058 // Update the all ports state on that device to disable
1059 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001060 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001061 return er
1062 }
1063
1064 //Update the device oper state and connection status
1065 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1066 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1067 dh.device = cloned
1068
1069 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001070 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001071 return er
1072 }
1073
1074 //get the child device for the parent device
1075 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1076 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001077 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001078 return err
1079 }
1080 for _, onuDevice := range onuDevices.Items {
1081
1082 // Update onu state as down in onu adapter
1083 onuInd := oop.OnuIndication{}
1084 onuInd.OperState = "down"
1085 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1086 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1087 if er != nil {
1088 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001089 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090 //Do not return here and continue to process other ONUs
1091 }
1092 }
1093 // * Discovered ONUs entries need to be cleared , since after OLT
1094 // is up, it starts sending discovery indications again* /
1095 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001096 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001097 return nil
1098 */
Himani Chawla4d908332020-08-31 12:30:20 +05301099 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001100 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001101 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001102}
1103
Himani Chawla6d2ae152020-09-02 13:11:20 +05301104// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001105// #################################################################################
1106
1107// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301108// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001109
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001110//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301111func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001112 dh.lockDevice.RLock()
1113 pOnuDeviceEntry := dh.pOnuOmciDevice
1114 if aWait && pOnuDeviceEntry == nil {
1115 //keep the read sema short to allow for subsequent write
1116 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001117 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001118 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1119 // so it might be needed to wait here for that event with some timeout
1120 select {
1121 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001122 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001123 return nil
1124 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001125 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001126 // if written now, we can return the written value without sema
1127 return dh.pOnuOmciDevice
1128 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001129 }
mpagenko3af1f032020-06-10 08:53:41 +00001130 dh.lockDevice.RUnlock()
1131 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001132}
1133
Himani Chawla6d2ae152020-09-02 13:11:20 +05301134//setOnuDeviceEntry sets the ONU device entry within the handler
1135func (dh *deviceHandler) setOnuDeviceEntry(
1136 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001137 dh.lockDevice.Lock()
1138 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001139 dh.pOnuOmciDevice = apDeviceEntry
1140 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001141}
1142
Himani Chawla6d2ae152020-09-02 13:11:20 +05301143//addOnuDeviceEntry creates a new ONU device or returns the existing
1144func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001145 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146
Himani Chawla6d2ae152020-09-02 13:11:20 +05301147 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001148 if deviceEntry == nil {
1149 /* costum_me_map in python code seems always to be None,
1150 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1151 /* also no 'clock' argument - usage open ...*/
1152 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001153 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001154 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301156 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001157 // fire deviceEntry ready event to spread to possibly waiting processing
1158 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001159 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001160 } else {
divyadesai4d299552020-08-18 07:13:49 +00001161 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001162 }
1163 // might be updated with some error handling !!!
1164 return nil
1165}
1166
1167// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301168func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001169 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1170 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1171
1172 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001173
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001174 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001175 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1176 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001177 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1178 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1179 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1180 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1181 }
1182 } else {
1183 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1184 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001185 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001186 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1187 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1188 // 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 +00001189 // 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 +00001190 // so let's just try to keep it simple ...
1191 /*
1192 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1193 if err != nil || device == nil {
1194 //TODO: needs to handle error scenarios
1195 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1196 return errors.New("Voltha Device not found")
1197 }
1198 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001199
Himani Chawla6d2ae152020-09-02 13:11:20 +05301200 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001201 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301202 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301203 return err
1204 }
mpagenko3af1f032020-06-10 08:53:41 +00001205 } else {
divyadesai4d299552020-08-18 07:13:49 +00001206 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001207 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001208 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001209 if !dh.reconciling {
1210 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1211 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1212 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1213 }
1214 } else {
1215 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1216 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001217 }
mpagenko3af1f032020-06-10 08:53:41 +00001218 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001219
1220 /* this might be a good time for Omci Verify message? */
1221 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301222 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001223 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001224 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301225 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001226
1227 /* give the handler some time here to wait for the OMCi verification result
1228 after Timeout start and try MibUpload FSM anyway
1229 (to prevent stopping on just not supported OMCI verification from ONU) */
1230 select {
1231 case <-time.After(2 * time.Second):
1232 logger.Warn("omci start-verification timed out (continue normal)")
1233 case testresult := <-verifyExec:
1234 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1235 }
1236
1237 /* In py code it looks earlier (on activate ..)
1238 # Code to Run OMCI Test Action
1239 kwargs_omci_test_action = {
1240 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1241 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1242 }
1243 serial_number = device.serial_number
1244 self._test_request = OmciTestRequest(self.core_proxy,
1245 self.omci_agent, self.device_id,
1246 AniG, serial_number,
1247 self.logical_device_id,
1248 exclusive=False,
1249 **kwargs_omci_test_action)
1250 ...
1251 # Start test requests after a brief pause
1252 if not self._test_request_started:
1253 self._test_request_started = True
1254 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1255 reactor.callLater(tststart, self._test_request.start_collector)
1256
1257 */
1258 /* which is then: in omci_test_request.py : */
1259 /*
1260 def start_collector(self, callback=None):
1261 """
1262 Start the collection loop for an adapter if the frequency > 0
1263
1264 :param callback: (callable) Function to call to collect PM data
1265 """
1266 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1267 if callback is None:
1268 callback = self.perform_test_omci
1269
1270 if self.lc is None:
1271 self.lc = LoopingCall(callback)
1272
1273 if self.default_freq > 0:
1274 self.lc.start(interval=self.default_freq / 10)
1275
1276 def perform_test_omci(self):
1277 """
1278 Perform the initial test request
1279 """
1280 ani_g_entities = self._device.configuration.ani_g_entities
1281 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1282 is not None else None
1283 self._entity_id = ani_g_entities_ids[0]
1284 self.logger.info('perform-test', entity_class=self._entity_class,
1285 entity_id=self._entity_id)
1286 try:
1287 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1288 result = yield self._device.omci_cc.send(frame)
1289 if not result.fields['omci_message'].fields['success_code']:
1290 self.logger.info('Self-Test Submitted Successfully',
1291 code=result.fields[
1292 'omci_message'].fields['success_code'])
1293 else:
1294 raise TestFailure('Test Failure: {}'.format(
1295 result.fields['omci_message'].fields['success_code']))
1296 except TimeoutError as e:
1297 self.deferred.errback(failure.Failure(e))
1298
1299 except Exception as e:
1300 self.logger.exception('perform-test-Error', e=e,
1301 class_id=self._entity_class,
1302 entity_id=self._entity_id)
1303 self.deferred.errback(failure.Failure(e))
1304
1305 */
1306
1307 // PM related heartbeat??? !!!TODO....
1308 //self._heartbeat.enabled = True
1309
mpagenko1cc3cb42020-07-27 15:24:38 +00001310 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1311 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1312 * 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 +05301313 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001314 */
1315 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001316 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001317 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001318 if pMibUlFsm.Is(ulStDisabled) {
1319 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001320 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001321 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301322 }
1323 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1324 //Determine ONU status and start/re-start MIB Synchronization tasks
1325 //Determine if this ONU has ever synchronized
1326 if true { //TODO: insert valid check
1327 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001328 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 +00001329 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001330 }
Himani Chawla4d908332020-08-31 12:30:20 +05301331 } else {
1332 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001333 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 +00001334 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301335 }
1336 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1337 //Examine the MIB Data Sync
1338 // callbacks to be handled:
1339 // Event(ulEvSuccess)
1340 // Event(ulEvTimeout)
1341 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001343 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001344 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001345 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001346 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001347 }
1348 } else {
divyadesai4d299552020-08-18 07:13:49 +00001349 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001350 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001351 }
1352 return nil
1353}
1354
Himani Chawla6d2ae152020-09-02 13:11:20 +05301355func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001356 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001357 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
mpagenko3af1f032020-06-10 08:53:41 +00001358 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001359 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001360
mpagenko900ee4b2020-10-12 11:56:34 +00001361 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1362 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1363 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1364 if err := dh.resetFsms(); err != nil {
1365 logger.Errorw("error-updateInterface at FSM stop",
1366 log.Fields{"device-id": dh.deviceID, "error": err})
1367 // abort: system behavior is just unstable ...
1368 return err
1369 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001370 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
mpagenko2418ab02020-11-12 12:58:06 +00001371 _ = dh.deleteDevicePersistencyData() //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001372
1373 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1374 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1375 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301376 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001377 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001378 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001379 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001380 }
mpagenko900ee4b2020-10-12 11:56:34 +00001381 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001382
1383 //TODO!!! remove existing traffic profiles
1384 /* from py code, if TP's exist, remove them - not yet implemented
1385 self._tp = dict()
1386 # Let TP download happen again
1387 for uni_id in self._tp_service_specific_task:
1388 self._tp_service_specific_task[uni_id].clear()
1389 for uni_id in self._tech_profile_download_done:
1390 self._tech_profile_download_done[uni_id].clear()
1391 */
1392
1393 dh.disableUniPortStateUpdate()
1394
mpagenkofc4f56e2020-11-04 17:17:49 +00001395 dh.deviceReason = "stopping-openomci"
1396 dh.ReadyForSpecificOmciConfig = false
1397
mpagenko3af1f032020-06-10 08:53:41 +00001398 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001399 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001400 logger.Errorw("error-DeviceReasonUpdate to stopping-openomci",
divyadesai4d299552020-08-18 07:13:49 +00001401 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001402 // abort: system behavior is just unstable ...
1403 return err
1404 }
mpagenko3af1f032020-06-10 08:53:41 +00001405
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001406 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1407 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001408 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1409 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001410 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001411 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001412 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001413 // abort: system behavior is just unstable ...
1414 return err
1415 }
1416 } else {
divyadesai4d299552020-08-18 07:13:49 +00001417 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001418 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001419 return nil
1420}
1421
mpagenko900ee4b2020-10-12 11:56:34 +00001422func (dh *deviceHandler) resetFsms() error {
1423 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1424 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1425 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1426 // and using the stop/reset event should never harm
1427
1428 pDevEntry := dh.getOnuDeviceEntry(false)
1429 if pDevEntry == nil {
1430 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1431 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1432 }
1433
1434 //the MibSync FSM might be active all the ONU-active time,
1435 // hence it must be stopped unconditionally
1436 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1437 if pMibUlFsm != nil {
1438 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1439 }
1440 //MibDownload may run
1441 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1442 if pMibDlFsm != nil {
1443 _ = pMibDlFsm.Event(dlEvReset)
1444 }
1445 //port lock/unlock FSM's may be active
1446 if dh.pUnlockStateFsm != nil {
1447 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1448 }
1449 if dh.pLockStateFsm != nil {
1450 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1451 }
1452 //techProfile related PonAniConfigFsm FSM may be active
1453 if dh.pOnuTP != nil {
1454 // should always be the case here
1455 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1456 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001457 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1458 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1459 }
mpagenko900ee4b2020-10-12 11:56:34 +00001460 }
1461 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001462 // reset the possibly existing VlanConfigFsm
1463 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1464 //VlanFilterFsm exists and was already started
1465 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1466 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001467 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001468 // no need to remove specific data
1469 pVlanFilterFsm.RequestClearPersistency(false)
1470 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001471 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1472 }
1473 }
1474 }
1475 }
1476 //TODO!!! care about PM/Alarm processing once started
1477 return nil
1478}
1479
Himani Chawla6d2ae152020-09-02 13:11:20 +05301480func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001481 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 +05301482 if !dh.reconciling {
1483 //initiate DevStateUpdate
1484 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1485 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001486 logger.Errorw("error-DeviceReasonUpdate to mibsync-complete", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301487 "device-id": dh.deviceID, "error": err})
1488 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001489 logger.Infow("dev reason updated to MibSync complete", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301490 }
1491 } else {
1492 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1493 log.Fields{"device-id": dh.deviceID})
1494 }
1495 //set internal state anyway - as it was done
1496 dh.deviceReason = "discovery-mibsync-complete"
1497
Himani Chawla6d2ae152020-09-02 13:11:20 +05301498 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenkoa40e99a2020-11-17 13:50:39 +00001499 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301500 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301501 for _, mgmtEntityID := range unigInstKeys {
1502 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1503 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301504 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301505 i++
1506 }
1507 } else {
1508 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1509 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301510 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301511 for _, mgmtEntityID := range veipInstKeys {
1512 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1513 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301514 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301515 i++
1516 }
1517 } else {
1518 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1519 }
1520 if i == 0 {
1521 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1522 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001523 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1524 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1525 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1526 * disable/enable toggling here to allow traffic
1527 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1528 * like the py comment says:
1529 * # start by locking all the unis till mib sync and initial mib is downloaded
1530 * # this way we can capture the port down/up events when we are ready
1531 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301532
mpagenkoa40e99a2020-11-17 13:50:39 +00001533 // Init Uni Ports to Admin locked state
1534 // *** should generate UniLockStateDone event *****
1535 if dh.pLockStateFsm == nil {
1536 dh.createUniLockFsm(true, UniLockStateDone)
1537 } else { //LockStateFSM already init
1538 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
1539 dh.runUniLockFsm(true)
1540 }
1541}
1542
1543func (dh *deviceHandler) processUniLockStateDoneEvent(devEvent OnuDeviceEvent) {
1544 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301545 /* Mib download procedure -
1546 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1547 */
mpagenkoa40e99a2020-11-17 13:50:39 +00001548 pDevEntry := dh.getOnuDeviceEntry(false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301549 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1550 if pMibDlFsm != nil {
1551 if pMibDlFsm.Is(dlStDisabled) {
1552 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001553 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301554 // maybe try a FSM reset and then again ... - TODO!!!
1555 } else {
1556 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1557 // maybe use more specific states here for the specific download steps ...
1558 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001559 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301560 } else {
1561 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1562 //Begin MIB data download (running autonomously)
1563 }
1564 }
1565 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001566 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001567 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301568 // maybe try a FSM reset and then again ... - TODO!!!
1569 }
1570 /***** Mib download started */
1571 } else {
1572 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1573 }
1574}
1575
Himani Chawla6d2ae152020-09-02 13:11:20 +05301576func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001577 logger.Debugw("MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301578 //initiate DevStateUpdate
1579 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001580 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1581 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301582 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1583 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1584 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1585 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1586 } else {
1587 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1588 }
1589 } else {
1590 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1591 log.Fields{"device-id": dh.deviceID})
1592 }
1593 if !dh.reconciling {
1594 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1595 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenkofc4f56e2020-11-04 17:17:49 +00001596 logger.Errorw("error-DeviceReasonUpdate to initial-mib-downloaded",
Himani Chawla26e555c2020-08-31 12:30:20 +05301597 log.Fields{"device-id": dh.deviceID, "error": err})
1598 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001599 logger.Infow("dev reason updated to initial-mib-downloaded", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301600 }
1601 } else {
1602 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1603 log.Fields{"device-id": dh.deviceID})
1604 }
1605 //set internal state anyway - as it was done
1606 dh.deviceReason = "initial-mib-downloaded"
mpagenkofc4f56e2020-11-04 17:17:49 +00001607 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301608 // *** should generate UniUnlockStateDone event *****
1609 if dh.pUnlockStateFsm == nil {
1610 dh.createUniLockFsm(false, UniUnlockStateDone)
1611 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301612 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301613 dh.runUniLockFsm(false)
1614 }
1615}
1616
Himani Chawla6d2ae152020-09-02 13:11:20 +05301617func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001618 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301619
1620 if !dh.reconciling {
1621 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1622 raisedTs := time.Now().UnixNano()
1623 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1624 } else {
1625 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1626 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301627 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001628 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301629 }
1630}
1631
mpagenko900ee4b2020-10-12 11:56:34 +00001632func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1633 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1634 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1635 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1636 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1637 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1638 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1639 }
1640
mpagenkofc4f56e2020-11-04 17:17:49 +00001641 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{
mpagenko900ee4b2020-10-12 11:56:34 +00001642 "reason": "omci-admin-lock", "device-id": dh.deviceID})
1643 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1644 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
1645 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1646 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1647 }
1648 dh.deviceReason = "omci-admin-lock"
1649
1650 //transfer the modified logical uni port state
1651 dh.disableUniPortStateUpdate()
mpagenko900ee4b2020-10-12 11:56:34 +00001652}
1653
1654func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1655 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1656 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1657 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1658 voltha.OperStatus_ACTIVE); err != nil {
1659 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1660 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1661 }
1662
1663 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1664 "reason": "onu-reenabled", "device-id": dh.deviceID})
1665 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1666 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
1667 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1668 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1669 }
1670 dh.deviceReason = "onu-reenabled"
1671
1672 //transfer the modified logical uni port state
1673 dh.enableUniPortStateUpdate()
1674}
1675
Himani Chawla6d2ae152020-09-02 13:11:20 +05301676func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001677 if devEvent == OmciAniConfigDone {
1678 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1679 // attention: the device reason update is done based on ONU-UNI-Port related activity
1680 // - which may cause some inconsistency
1681 if dh.deviceReason != "tech-profile-config-download-success" {
1682 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
1683 if !dh.reconciling {
1684 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1685 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1686 logger.Errorw("error-DeviceReasonUpdate to tech-profile-config-download-success",
1687 log.Fields{"device-id": dh.deviceID, "error": err})
1688 } else {
1689 logger.Infow("update dev reason to tech-profile-config-download-success",
1690 log.Fields{"device-id": dh.deviceID})
1691 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301692 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001693 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
Himani Chawla26e555c2020-08-31 12:30:20 +05301694 log.Fields{"device-id": dh.deviceID})
1695 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001696 //set internal state anyway - as it was done
1697 dh.deviceReason = "tech-profile-config-download-success"
Himani Chawla26e555c2020-08-31 12:30:20 +05301698 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001699 if dh.reconciling {
1700 go dh.reconcileDeviceFlowConfig()
1701 }
1702 } else { // should be the OmciAniResourceRemoved block
1703 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1704 // attention: the device reason update is done based on ONU-UNI-Port related activity
1705 // - which may cause some inconsistency
1706 if dh.deviceReason != "tech-profile-config-delete-success" {
1707 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
1708 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-delete-success"); err != nil {
1709 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1710 logger.Errorw("error-DeviceReasonUpdate to tech-profile-config-delete-success",
1711 log.Fields{"device-id": dh.deviceID, "error": err})
1712 } else {
1713 logger.Infow("update dev reason to tech-profile-config-delete-success",
1714 log.Fields{"device-id": dh.deviceID})
1715 }
1716 //set internal state anyway - as it was done
1717 dh.deviceReason = "tech-profile-config-delete-success"
1718 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001719 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301720}
1721
mpagenkofc4f56e2020-11-04 17:17:49 +00001722func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301723 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001724 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301725 // attention: the device reason update is done based on ONU-UNI-Port related activity
1726 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301727
mpagenkofc4f56e2020-11-04 17:17:49 +00001728 if aDevEvent == OmciVlanFilterAddDone {
1729 if dh.deviceReason != "omci-flows-pushed" {
1730 // which may be the case from some previous actvity on another UNI Port of the ONU
1731 // or even some previous flow add activity on the same port
1732 if !dh.reconciling {
1733 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1734 logger.Errorw("error-DeviceReasonUpdate to omci-flows-pushed",
1735 log.Fields{"device-id": dh.deviceID, "error": err})
1736 } else {
1737 logger.Infow("updated dev reason to omci-flows-pushed",
1738 log.Fields{"device-id": dh.deviceID})
1739 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001740 } else {
mpagenkofc4f56e2020-11-04 17:17:49 +00001741 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001742 log.Fields{"device-id": dh.deviceID})
1743 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001744 //set internal state anyway - as it was done
1745 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001746
mpagenkofc4f56e2020-11-04 17:17:49 +00001747 if dh.reconciling {
1748 go dh.reconcileMetrics()
1749 }
1750 }
1751 } else {
1752 if dh.deviceReason != "omci-flows-deleted" {
1753 //not relevant for reconcile
1754 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-deleted"); err != nil {
1755 logger.Errorw("error-DeviceReasonUpdate to omci-flows-deleted",
1756 log.Fields{"device-id": dh.deviceID, "error": err})
1757 } else {
1758 logger.Infow("updated dev reason to omci-flows-deleted",
1759 log.Fields{"device-id": dh.deviceID})
1760 }
1761 //set internal state anyway - as it was done
1762 dh.deviceReason = "omci-flows-deleted"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001763 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301764 }
1765}
1766
Himani Chawla6d2ae152020-09-02 13:11:20 +05301767//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1768func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301769 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001770 case MibDatabaseSync:
1771 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301772 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001773 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001774 case UniLockStateDone:
1775 {
1776 dh.processUniLockStateDoneEvent(devEvent)
1777 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001778 case MibDownloadDone:
1779 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301780 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001781 }
1782 case UniUnlockStateDone:
1783 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301784 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001785 }
mpagenko900ee4b2020-10-12 11:56:34 +00001786 case UniEnableStateDone:
1787 {
1788 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001789 }
1790 case UniDisableStateDone:
1791 {
1792 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001793 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001794 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001795 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301796 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001797 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001798 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001799 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301800 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001801 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001802 default:
1803 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001804 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001805 }
1806 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001807}
1808
Himani Chawla6d2ae152020-09-02 13:11:20 +05301809func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001810 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301811 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301812 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001813 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301814 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001815 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301816 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301817 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301819 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001821 //store UniPort with the System-PortNumber key
1822 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001823 if !dh.reconciling {
1824 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301825 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001826 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1827 } //error logging already within UniPort method
1828 } else {
1829 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1830 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831 }
1832 }
1833}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001834
mpagenko3af1f032020-06-10 08:53:41 +00001835// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301836func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001837 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301838 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001839 // with following remark:
1840 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1841 // # load on the core
1842
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001843 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001844
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001845 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001846 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301847 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001848 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301849 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001850 if !dh.reconciling {
1851 //maybe also use getter functions on uniPort - perhaps later ...
1852 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1853 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001854 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001855 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1856 }
mpagenko3af1f032020-06-10 08:53:41 +00001857 }
1858 }
1859}
1860
1861// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301862func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001863 // compare enableUniPortStateUpdate() above
1864 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1865 for uniNo, uniPort := range dh.uniEntityMap {
1866 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301867 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001868 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301869 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001870 //maybe also use getter functions on uniPort - perhaps later ...
1871 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001872 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001873 }
1874}
1875
1876// ONU_Active/Inactive announcement on system KAFKA bus
1877// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301878func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001879 var de voltha.DeviceEvent
1880 eventContext := make(map[string]string)
1881 //Populating event context
1882 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301883 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001884 if err != nil || parentDevice == nil {
1885 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301886 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001887 }
1888 oltSerialNumber := parentDevice.SerialNumber
1889
1890 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1891 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1892 eventContext["serial-number"] = dh.device.SerialNumber
1893 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301894 eventContext["device_id"] = aDeviceID
1895 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001896 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001897 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001898
1899 /* Populating device event body */
1900 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301901 de.ResourceId = aDeviceID
1902 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001903 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1904 de.Description = fmt.Sprintf("%s Event - %s - %s",
1905 cEventObjectType, cOnuActivatedEvent, "Raised")
1906 } else {
1907 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1908 de.Description = fmt.Sprintf("%s Event - %s - %s",
1909 cEventObjectType, cOnuActivatedEvent, "Cleared")
1910 }
1911 /* Send event to KAFKA */
1912 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1913 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301914 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001915 }
1916 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301917 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001918}
1919
Himani Chawla4d908332020-08-31 12:30:20 +05301920// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301921func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001922 chLSFsm := make(chan Message, 2048)
1923 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301924 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001925 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001926 sFsmName = "LockStateFSM"
1927 } else {
divyadesai4d299552020-08-18 07:13:49 +00001928 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001929 sFsmName = "UnLockStateFSM"
1930 }
mpagenko3af1f032020-06-10 08:53:41 +00001931
Himani Chawla6d2ae152020-09-02 13:11:20 +05301932 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001933 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001934 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001935 return
1936 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301937 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001938 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001939 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301940 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001941 dh.pLockStateFsm = pLSFsm
1942 } else {
1943 dh.pUnlockStateFsm = pLSFsm
1944 }
1945 dh.runUniLockFsm(aAdminState)
1946 } else {
divyadesai4d299552020-08-18 07:13:49 +00001947 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001948 }
1949}
1950
1951// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301952func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001953 /* Uni Port lock/unlock procedure -
1954 ***** should run via 'adminDone' state and generate the argument requested event *****
1955 */
1956 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301957 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001958 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1959 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1960 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001961 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301962 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001963 }
1964 } else {
1965 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1966 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1967 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001968 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301969 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001970 }
1971 }
1972 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001973 if pLSStatemachine.Is(uniStDisabled) {
1974 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001975 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1976 // maybe try a FSM reset and then again ... - TODO!!!
1977 } else {
1978 /***** LockStateFSM started */
1979 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001980 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001981 }
1982 } else {
1983 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001984 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001985 // maybe try a FSM reset and then again ... - TODO!!!
1986 }
1987 } else {
divyadesai4d299552020-08-18 07:13:49 +00001988 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001989 // maybe try a FSM reset and then again ... - TODO!!!
1990 }
1991}
1992
Himani Chawla6d2ae152020-09-02 13:11:20 +05301993//setBackend provides a DB backend for the specified path on the existing KV client
1994func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001995 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1996 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001997 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001998 kvbackend := &db.Backend{
1999 Client: dh.pOpenOnuAc.kvClient,
2000 StoreType: dh.pOpenOnuAc.KVStoreType,
2001 /* address config update acc. to [VOL-2736] */
2002 Address: addr,
2003 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2004 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002005
mpagenkoaf801632020-07-03 10:00:42 +00002006 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002007}
Himani Chawla6d2ae152020-09-02 13:11:20 +05302008func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302009 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002010
mpagenkodff5dda2020-08-28 11:52:01 +00002011 for _, field := range flow.GetOfbFields(apFlowItem) {
2012 switch field.Type {
2013 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2014 {
mpagenko01e726e2020-10-23 09:45:29 +00002015 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002016 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2017 }
mpagenko01e726e2020-10-23 09:45:29 +00002018 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002019 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2020 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302021 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002022 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302023 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2024 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002025 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2026 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002027 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2028 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302029 return
mpagenkodff5dda2020-08-28 11:52:01 +00002030 }
2031 }
mpagenko01e726e2020-10-23 09:45:29 +00002032 */
mpagenkodff5dda2020-08-28 11:52:01 +00002033 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2034 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302035 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002036 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302037 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002038 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302039 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002040 }
mpagenko01e726e2020-10-23 09:45:29 +00002041 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302042 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002043 }
2044 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2045 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302046 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002047 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002048 "PCP": loAddPcp})
2049 }
2050 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2051 {
mpagenko01e726e2020-10-23 09:45:29 +00002052 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002053 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2054 }
2055 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2056 {
mpagenko01e726e2020-10-23 09:45:29 +00002057 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002058 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2059 }
2060 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2061 {
mpagenko01e726e2020-10-23 09:45:29 +00002062 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002063 "IPv4-DST": field.GetIpv4Dst()})
2064 }
2065 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2066 {
mpagenko01e726e2020-10-23 09:45:29 +00002067 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002068 "IPv4-SRC": field.GetIpv4Src()})
2069 }
2070 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2071 {
mpagenko01e726e2020-10-23 09:45:29 +00002072 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002073 "Metadata": field.GetTableMetadata()})
2074 }
2075 /*
2076 default:
2077 {
2078 //all other entires ignored
2079 }
2080 */
2081 }
2082 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302083}
mpagenkodff5dda2020-08-28 11:52:01 +00002084
Himani Chawla6d2ae152020-09-02 13:11:20 +05302085func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002086 for _, action := range flow.GetActions(apFlowItem) {
2087 switch action.Type {
2088 /* not used:
2089 case of.OfpActionType_OFPAT_OUTPUT:
2090 {
mpagenko01e726e2020-10-23 09:45:29 +00002091 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002092 "Output": action.GetOutput()})
2093 }
2094 */
2095 case of.OfpActionType_OFPAT_PUSH_VLAN:
2096 {
mpagenko01e726e2020-10-23 09:45:29 +00002097 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002098 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2099 }
2100 case of.OfpActionType_OFPAT_SET_FIELD:
2101 {
2102 pActionSetField := action.GetSetField()
2103 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00002104 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002105 "OxcmClass": pActionSetField.Field.OxmClass})
2106 }
2107 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302108 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002109 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302110 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002111 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302112 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002113 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302114 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002115 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002116 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002117 "Type": pActionSetField.Field.GetOfbField().Type})
2118 }
2119 }
2120 /*
2121 default:
2122 {
2123 //all other entires ignored
2124 }
2125 */
2126 }
2127 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302128}
2129
2130//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302131func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302132 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2133 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2134 var loAddPcp, loSetPcp uint8
2135 var loIPProto uint32
2136 /* the TechProfileId is part of the flow Metadata - compare also comment within
2137 * OLT-Adapter:openolt_flowmgr.go
2138 * Metadata 8 bytes:
2139 * Most Significant 2 Bytes = Inner VLAN
2140 * Next 2 Bytes = Tech Profile ID(TPID)
2141 * Least Significant 4 Bytes = Port ID
2142 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2143 * subscriber related flows.
2144 */
2145
2146 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2147 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002148 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302149 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002150 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302151 }
2152 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002153 loCookie := apFlowItem.GetCookie()
2154 loCookieSlice := []uint64{loCookie}
2155 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2156 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302157
2158 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002159 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302160 if loIPProto == 2 {
2161 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2162 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002163 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2164 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302165 return nil
2166 }
mpagenko01e726e2020-10-23 09:45:29 +00002167 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302168 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002169
2170 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002171 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002172 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2173 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2174 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2175 //TODO!!: Use DeviceId within the error response to rwCore
2176 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002177 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002178 }
2179 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002180 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002181 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2182 } else {
2183 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2184 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2185 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302186 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002187 }
mpagenko01e726e2020-10-23 09:45:29 +00002188 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002189 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302190 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002191 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2192 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002193 }
mpagenko01e726e2020-10-23 09:45:29 +00002194 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002195 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002196}
2197
2198//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2199func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2200 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2201 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2202 //no extra check is done on the rule parameters
2203 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2204 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2205 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2206 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002207 // - 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 +00002208 loCookie := apFlowItem.GetCookie()
2209 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2210
2211 /* TT related temporary workaround - should not be needed anymore
2212 for _, field := range flow.GetOfbFields(apFlowItem) {
2213 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2214 loIPProto := field.GetIpProto()
2215 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2216 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2217 if loIPProto == 2 {
2218 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2219 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2220 log.Fields{"device-id": dh.deviceID})
2221 return nil
2222 }
2223 }
2224 } //for all OfbFields
2225 */
2226
2227 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2228 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2229 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002230 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002231 log.Fields{"device-id": dh.deviceID})
2232 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002233 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2234 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2235
mpagenko01e726e2020-10-23 09:45:29 +00002236 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002237}
2238
Himani Chawla26e555c2020-08-31 12:30:20 +05302239// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002240func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2241 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002242 chVlanFilterFsm := make(chan Message, 2048)
2243
Himani Chawla6d2ae152020-09-02 13:11:20 +05302244 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002245 if pDevEntry == nil {
2246 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302247 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002248 }
2249
2250 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002251 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2252 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002253 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302254 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002255 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2256 if pVlanFilterStatemachine != nil {
2257 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2258 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2259 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302260 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002261 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302262 /***** UniVlanConfigFsm started */
2263 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2264 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2265 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002266 } else {
2267 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2268 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302269 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002270 }
2271 } else {
2272 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2273 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302274 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002275 }
2276 } else {
2277 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2278 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302279 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002280 }
2281 return nil
2282}
2283
mpagenkofc4f56e2020-11-04 17:17:49 +00002284//VerifyVlanConfigRequest checks on existence of a given uniPort
2285// and starts verification of flow config based on that
2286func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2287 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2288 var pCurrentUniPort *onuUniPort
2289 for _, uniPort := range dh.uniEntityMap {
2290 // only if this port is validated for operState transfer
2291 if uniPort.uniID == uint8(aUniID) {
2292 pCurrentUniPort = uniPort
2293 break //found - end search loop
2294 }
2295 }
2296 if pCurrentUniPort == nil {
2297 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2298 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2299 return
2300 }
2301 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2302}
2303
mpagenkodff5dda2020-08-28 11:52:01 +00002304//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302305func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002306 //TODO!! verify and start pending flow configuration
2307 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2308 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302309 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002310 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2311 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2312 if pVlanFilterStatemachine != nil {
2313 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2314 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2315 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2316 } else {
2317 /***** UniVlanConfigFsm continued */
2318 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2319 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2320 "UniPort": apUniPort.portNo})
2321 }
2322 } else {
2323 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2324 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2325 }
2326 } else {
2327 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2328 "device-id": dh.deviceID})
2329 }
2330
2331 } // else: nothing to do
2332}
2333
2334//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2335// 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 +05302336func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002337 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2338 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2339 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302340 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002341}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002342
2343//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2344//available for potential reconcilement
2345
2346func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2347
2348 if dh.reconciling {
2349 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2350 return nil
2351 }
mpagenko2418ab02020-11-12 12:58:06 +00002352 logger.Debugw("Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002353
2354 pDevEntry := dh.getOnuDeviceEntry(true)
2355 if pDevEntry == nil {
2356 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2357 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2358 }
2359 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2360
2361 pDevEntry.lockOnuKVStoreMutex()
2362 defer pDevEntry.unlockOnuKVStoreMutex()
2363
2364 // deadline context to ensure completion of background routines waited for
2365 //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 +05302366 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002367 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2368
2369 pDevEntry.resetKvProcessingErrorIndication()
2370 var wg sync.WaitGroup
2371 wg.Add(1) // for the 1 go routine to finish
2372
2373 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002374 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002375
2376 return pDevEntry.getKvProcessingErrorIndication()
2377}
2378
mpagenko01e726e2020-10-23 09:45:29 +00002379func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002380 defer cancel() //ensure termination of context (may be pro forma)
2381 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002382 logger.Debugw("WaitGroup processing completed", log.Fields{
2383 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002384}
2385
2386func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2387 var errStr string = ""
2388 for _, err := range errS {
2389 if err != nil {
2390 errStr = errStr + err.Error() + " "
2391 }
2392 }
2393 if errStr != "" {
2394 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2395 }
2396 return nil
2397}