blob: 414abaf154279a1ccf51b9be2c054cefcb12d888 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/hex"
23 "errors"
24 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000033 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
mpagenkoaf801632020-07-03 10:00:42 +000034 "github.com/opencord/voltha-lib-go/v3/pkg/db"
mpagenkodff5dda2020-08-28 11:52:01 +000035 flow "github.com/opencord/voltha-lib-go/v3/pkg/flows"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000036 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000037 vc "github.com/opencord/voltha-protos/v3/go/common"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000038 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
mpagenkodff5dda2020-08-28 11:52:01 +000039 "github.com/opencord/voltha-protos/v3/go/openflow_13"
40 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
41 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000042 oop "github.com/opencord/voltha-protos/v3/go/openolt"
43 "github.com/opencord/voltha-protos/v3/go/voltha"
44)
45
46/*
47// Constants for number of retries and for timeout
48const (
49 MaxRetry = 10
50 MaxTimeOutInMs = 500
51)
52*/
53
mpagenko1cc3cb42020-07-27 15:24:38 +000054const (
55 // events of Device FSM
56 devEvDeviceInit = "devEvDeviceInit"
57 devEvGrpcConnected = "devEvGrpcConnected"
58 devEvGrpcDisconnected = "devEvGrpcDisconnected"
59 devEvDeviceUpInd = "devEvDeviceUpInd"
60 devEvDeviceDownInd = "devEvDeviceDownInd"
61)
62const (
63 // states of Device FSM
64 devStNull = "devStNull"
65 devStDown = "devStDown"
66 devStInit = "devStInit"
67 devStConnected = "devStConnected"
68 devStUp = "devStUp"
69)
70
Holger Hildebrandt24d51952020-05-04 14:03:42 +000071//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
72const (
Himani Chawla4d908332020-08-31 12:30:20 +053073 pon = voltha.EventSubCategory_PON
74 //olt = voltha.EventSubCategory_OLT
75 //ont = voltha.EventSubCategory_ONT
76 //onu = voltha.EventSubCategory_ONU
77 //nni = voltha.EventSubCategory_NNI
78 //service = voltha.EventCategory_SERVICE
79 //security = voltha.EventCategory_SECURITY
80 equipment = voltha.EventCategory_EQUIPMENT
81 //processing = voltha.EventCategory_PROCESSING
82 //environment = voltha.EventCategory_ENVIRONMENT
83 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000084)
85
86const (
87 cEventObjectType = "ONU"
88)
89const (
90 cOnuActivatedEvent = "ONU_ACTIVATED"
91)
92
Himani Chawla6d2ae152020-09-02 13:11:20 +053093//deviceHandler will interact with the ONU ? device.
94type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000095 deviceID string
96 DeviceType string
97 adminState string
98 device *voltha.Device
99 logicalDeviceID string
100 ProxyAddressID string
101 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530102 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000103 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000104
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000105 coreProxy adapterif.CoreProxy
106 AdapterProxy adapterif.AdapterProxy
107 EventProxy adapterif.EventProxy
108
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000109 pOpenOnuAc *OpenONUAC
110 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530111 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000112 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000113 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530114 pOnuTP *onuUniTechProf
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000115 exitChannel chan int
116 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000117 pOnuIndication *oop.OnuIndication
mpagenko3af1f032020-06-10 08:53:41 +0000118 deviceReason string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530119 pLockStateFsm *lockStateFsm
120 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000121
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000122 //flowMgr *OpenOltFlowMgr
123 //eventMgr *OpenOltEventMgr
124 //resourceMgr *rsrcMgr.OpenOltResourceMgr
125
126 //discOnus sync.Map
127 //onus sync.Map
128 //portStats *OpenOltStatisticsMgr
129 //metrics *pmmetrics.PmMetrics
mpagenkodff5dda2020-08-28 11:52:01 +0000130 stopCollector chan bool
131 stopHeartbeatCheck chan bool
132 activePorts sync.Map
Himani Chawla6d2ae152020-09-02 13:11:20 +0530133 uniEntityMap map[uint32]*onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000134 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
135 reconciling bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000136}
137
Himani Chawla6d2ae152020-09-02 13:11:20 +0530138//newDeviceHandler creates a new device handler
139func newDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
140 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000141 dh.coreProxy = cp
142 dh.AdapterProxy = ap
143 dh.EventProxy = ep
144 cloned := (proto.Clone(device)).(*voltha.Device)
145 dh.deviceID = cloned.Id
146 dh.DeviceType = cloned.Type
147 dh.adminState = "up"
148 dh.device = cloned
149 dh.pOpenOnuAc = adapter
150 dh.exitChannel = make(chan int, 1)
151 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000152 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153 dh.stopCollector = make(chan bool, 2)
154 dh.stopHeartbeatCheck = make(chan bool, 2)
155 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
156 dh.activePorts = sync.Map{}
157 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000159 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000160 dh.reconciling = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000161
162 // Device related state machine
163 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000164 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000165 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000166 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
167 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
168 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
169 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
170 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 },
172 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000173 "before_event": func(e *fsm.Event) { dh.logStateChange(e) },
174 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(e) },
175 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(e) },
176 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(e) },
177 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
178 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(e) },
179 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(e) },
180 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000181 },
182 )
mpagenkoaf801632020-07-03 10:00:42 +0000183
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184 return &dh
185}
186
Himani Chawla6d2ae152020-09-02 13:11:20 +0530187// start save the device to the data model
188func (dh *deviceHandler) start(ctx context.Context) {
divyadesai4d299552020-08-18 07:13:49 +0000189 logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 // Add the initial device to the local model
191 logger.Debug("device-handler-started")
192}
193
Himani Chawla4d908332020-08-31 12:30:20 +0530194/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000195// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530196func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197 logger.Debug("stopping-device-handler")
198 dh.exitChannel <- 1
199}
Himani Chawla4d908332020-08-31 12:30:20 +0530200*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201
202// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530203// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204
Himani Chawla6d2ae152020-09-02 13:11:20 +0530205//adoptOrReconcileDevice adopts the OLT device
206func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000207 logger.Debugw("Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000208
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000209 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000210 if dh.pDeviceStateFsm.Is(devStNull) {
211 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000212 logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
213 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000214 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 } else {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000216 logger.Debugw("AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000217 }
218
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219}
220
Himani Chawla6d2ae152020-09-02 13:11:20 +0530221func (dh *deviceHandler) processInterAdapterOMCIReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530222 msgBody := msg.GetBody()
223 omciMsg := &ic.InterAdapterOmciMessage{}
224 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
225 logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
226 "device-id": dh.deviceID, "error": err})
227 return err
228 }
229
230 //assuming omci message content is hex coded!
231 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
232 logger.Debugw("inter-adapter-recv-omci", log.Fields{
233 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
234 //receive_message(omci_msg.message)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530235 pDevEntry := dh.getOnuDeviceEntry(true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530236 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000237 if pDevEntry.PDevOmciCC != nil {
238 return pDevEntry.PDevOmciCC.receiveMessage(context.TODO(), omciMsg.Message)
239 }
240 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 +0530241 }
242 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000243 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530244}
245
Himani Chawla6d2ae152020-09-02 13:11:20 +0530246func (dh *deviceHandler) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530247 msgBody := msg.GetBody()
248 onuIndication := &oop.OnuIndication{}
249 if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
250 logger.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{
251 "device-id": dh.deviceID, "error": err})
252 return err
253 }
254
255 onuOperstate := onuIndication.GetOperState()
mpagenko900ee4b2020-10-12 11:56:34 +0000256 logger.Debugw("inter-adapter-recv-onu-ind", log.Fields{"device-id": dh.deviceID,
257 "OnuId": onuIndication.GetOnuId(),
Himani Chawla26e555c2020-08-31 12:30:20 +0530258 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
259 "SNR": onuIndication.GetSerialNumber()})
260
261 //interface related functions might be error checked ....
262 if onuOperstate == "up" {
263 _ = dh.createInterface(onuIndication)
264 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
265 _ = dh.updateInterface(onuIndication)
266 } else {
267 logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000268 return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530269 }
270 return nil
271}
272
Himani Chawla6d2ae152020-09-02 13:11:20 +0530273func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530274 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000275
276 pDevEntry := dh.getOnuDeviceEntry(true)
277 if pDevEntry == nil {
278 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
279 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
280 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530281 if dh.pOnuTP == nil {
282 //should normally not happen ...
283 logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
284 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000285 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530286 }
287 if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock") {
288 // I've seen cases for this request, where the device was already stopped
289 logger.Warnw("TechProf stopped: device-unreachable", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000290 return fmt.Errorf("device-unreachable: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530291 }
292
293 msgBody := msg.GetBody()
294 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
295 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
296 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
297 "device-id": dh.deviceID, "error": err})
298 return err
299 }
300
301 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000302 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
303 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530304 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000305 defer dh.pOnuTP.unlockTpProcMutex()
306 pDevEntry.lockOnuKVStoreMutex()
307 defer pDevEntry.unlockOnuKVStoreMutex()
308
309 if techProfMsg.UniId > 255 {
310 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
311 techProfMsg.UniId, dh.deviceID))
312 }
313 uniID := uint8(techProfMsg.UniId)
314
315 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530316 // if there has been some change for some uni TechProfilePath
317 //in order to allow concurrent calls to other dh instances we do not wait for execution here
318 //but doing so we can not indicate problems to the caller (who does what with that then?)
319 //by now we just assume straightforward successful execution
320 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
321 // possible problems to the caller later autonomously
322
323 // deadline context to ensure completion of background routines waited for
324 //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 +0530325 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530326 dctx, cancel := context.WithDeadline(context.Background(), deadline)
327
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000328 dh.pOnuTP.resetTpProcessingErrorIndication()
329 pDevEntry.resetKvProcessingErrorIndication()
330
Himani Chawla26e555c2020-08-31 12:30:20 +0530331 var wg sync.WaitGroup
332 wg.Add(2) // for the 2 go routines to finish
333 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000334 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
335 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000336 dh.waitForCompletion(cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000337
338 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530339 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000340 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530341 return nil
342}
343
Himani Chawla6d2ae152020-09-02 13:11:20 +0530344func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 msg *ic.InterAdapterMessage) error {
346
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000347 pDevEntry := dh.getOnuDeviceEntry(true)
348 if pDevEntry == nil {
349 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
350 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
351 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 if dh.pOnuTP == nil {
353 //should normally not happen ...
354 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
355 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000356 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 }
358
359 msgBody := msg.GetBody()
360 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
361 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
362 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
363 "device-id": dh.deviceID, "error": err})
364 return err
365 }
366
367 //compare TECH_PROFILE_DOWNLOAD_REQUEST
368 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000369 defer dh.pOnuTP.unlockTpProcMutex()
370 pDevEntry.lockOnuKVStoreMutex()
371 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530372
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000373 if delGemPortMsg.UniId > 255 {
374 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
375 delGemPortMsg.UniId, dh.deviceID))
376 }
377 uniID := uint8(delGemPortMsg.UniId)
Himani Chawla26e555c2020-08-31 12:30:20 +0530378
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
380 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530381 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 dctx, cancel := context.WithDeadline(context.Background(), deadline)
383
384 dh.pOnuTP.resetTpProcessingErrorIndication()
385 pDevEntry.resetKvProcessingErrorIndication()
386
387 var wg sync.WaitGroup
388 wg.Add(2) // for the 2 go routines to finish
389 go pDevEntry.deleteTpResource(dctx, uniID, delGemPortMsg.TpPath,
390 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
391 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
392 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000393 dh.waitForCompletion(cancel, &wg, "GemDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394
395 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
396 }
397 return nil
Himani Chawla26e555c2020-08-31 12:30:20 +0530398}
399
Himani Chawla6d2ae152020-09-02 13:11:20 +0530400func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402
403 pDevEntry := dh.getOnuDeviceEntry(true)
404 if pDevEntry == nil {
405 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
406 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
407 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530408 if dh.pOnuTP == nil {
409 //should normally not happen ...
410 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
411 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530413 }
414
415 msgBody := msg.GetBody()
416 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
417 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
418 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
419 "device-id": dh.deviceID, "error": err})
420 return err
421 }
422
423 //compare TECH_PROFILE_DOWNLOAD_REQUEST
424 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425 defer dh.pOnuTP.unlockTpProcMutex()
426 pDevEntry.lockOnuKVStoreMutex()
427 defer pDevEntry.unlockOnuKVStoreMutex()
428
429 if delTcontMsg.UniId > 255 {
430 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
431 delTcontMsg.UniId, dh.deviceID))
432 }
433 uniID := uint8(delTcontMsg.UniId)
434
435 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530436 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530437 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530438 dctx, cancel := context.WithDeadline(context.Background(), deadline)
439
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 dh.pOnuTP.resetTpProcessingErrorIndication()
441 pDevEntry.resetKvProcessingErrorIndication()
442
Himani Chawla26e555c2020-08-31 12:30:20 +0530443 var wg sync.WaitGroup
444 wg.Add(2) // for the 2 go routines to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 go pDevEntry.deleteTpResource(dctx, uniID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 cResourceTcont, delTcontMsg.AllocId, &wg)
447 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000449 dh.waitForCompletion(cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450
451 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 return nil
454}
455
Himani Chawla6d2ae152020-09-02 13:11:20 +0530456//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000457// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
458// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530459func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000460 msgID := msg.Header.Id
461 msgType := msg.Header.Type
462 fromTopic := msg.Header.FromTopic
463 toTopic := msg.Header.ToTopic
464 toDeviceID := msg.Header.ToDeviceId
465 proxyDeviceID := msg.Header.ProxyDeviceId
466 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
467 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
468
469 switch msgType {
470 case ic.InterAdapterMessageType_OMCI_REQUEST:
471 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000473 }
474 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
475 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530476 return dh.processInterAdapterONUIndReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000477 }
mpagenkoaf801632020-07-03 10:00:42 +0000478 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
479 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000481 }
482 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
483 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000485
mpagenkoaf801632020-07-03 10:00:42 +0000486 }
487 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
488 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000490 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000491 default:
492 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000493 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494 "msgType": msg.Header.Type, "device-id": dh.deviceID})
495 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000496 }
497 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000498}
499
mpagenkodff5dda2020-08-28 11:52:01 +0000500//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530501func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000502 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
mpagenko01e726e2020-10-23 09:45:29 +0000503 logger.Debugw("FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000504
mpagenko01e726e2020-10-23 09:45:29 +0000505 var retError error = nil
506 //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 +0000507 if apOfFlowChanges.ToRemove != nil {
508 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000509 if flowItem.GetCookie() == 0 {
mpagenko01e726e2020-10-23 09:45:29 +0000510 logger.Warnw("flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
511 "device-id": dh.deviceID})
512 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000513 continue
514 }
515 flowInPort := flow.GetInPort(flowItem)
516 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
mpagenko01e726e2020-10-23 09:45:29 +0000517 logger.Warnw("flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
518 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
519 continue
520 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000521 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000522 //this is some downstream flow, not regarded as error, just ignored
523 logger.Debugw("flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
524 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000525 continue
526 } else {
527 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530528 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000529 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
530 loUniPort = uniPort
531 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000532 logger.Warnw("flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
533 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
534 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
535 flowInPort, dh.deviceID)
536 continue
537 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000538 }
539 flowOutPort := flow.GetOutPort(flowItem)
mpagenko01e726e2020-10-23 09:45:29 +0000540 logger.Debugw("flow-remove port indications", log.Fields{
541 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000542 "uniPortName": loUniPort.name})
mpagenko01e726e2020-10-23 09:45:29 +0000543 err := dh.removeFlowItemFromUniPort(flowItem, loUniPort)
544 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000545 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000546 logger.Warnw("flow-remove processing error: continuing on checking further flows",
547 log.Fields{"device-id": dh.deviceID, "error": err})
548 retError = err
549 continue
550 //return err
551 } else { // if last setting succeeds, overwrite possibly previously set error
552 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000553 }
554 }
555 }
556 }
mpagenko01e726e2020-10-23 09:45:29 +0000557 if apOfFlowChanges.ToAdd != nil {
558 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
559 if flowItem.GetCookie() == 0 {
560 logger.Debugw("incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
561 "device-id": dh.deviceID})
562 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
563 continue
564 }
565 flowInPort := flow.GetInPort(flowItem)
566 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
567 logger.Warnw("flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
568 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
569 continue
570 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
571 } else if flowInPort == dh.ponPortNumber {
572 //this is some downstream flow
573 logger.Debugw("flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
574 "device-id": dh.deviceID, "inPort": flowInPort})
575 continue
576 } else {
577 // this is the relevant upstream flow
578 var loUniPort *onuUniPort
579 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
580 loUniPort = uniPort
581 } else {
582 logger.Warnw("flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
583 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
584 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
585 flowInPort, dh.deviceID)
586 continue
587 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
588 }
589 flowOutPort := flow.GetOutPort(flowItem)
590 logger.Debugw("flow-add port indications", log.Fields{
591 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
592 "uniPortName": loUniPort.name})
593 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
594 //try next flow after processing error
595 if err != nil {
596 logger.Warnw("flow-add processing error: continuing on checking further flows",
597 log.Fields{"device-id": dh.deviceID, "error": err})
598 retError = err
599 continue
600 //return err
601 } else { // if last setting succeeds, overwrite possibly previously set error
602 retError = nil
603 }
604 }
605 }
606 }
607 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000608}
609
Himani Chawla6d2ae152020-09-02 13:11:20 +0530610//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530611func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000612 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000613
mpagenko900ee4b2020-10-12 11:56:34 +0000614 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
615 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
mpagenko3af1f032020-06-10 08:53:41 +0000616 if dh.deviceReason != "omci-admin-lock" {
mpagenko900ee4b2020-10-12 11:56:34 +0000617 //running FSM's are stopped/reset here to avoid indirect stucking
618 // due to blocked OMCI transmission on disabled state
619 // but with possibly aborted FSM's there might be complications as the expected state
620 // after some re-enable would then be quite undefined
621 // maybe after re-enabling some additional checks would be required to possibly enforce new
622 // (reconcile-like) config (which would require some indication from 'aborted' FSM's first)
623 // for now let's assume no running FSM is active at this time point here ... -> TODO!!!
624 if err := dh.resetFsms(); err != nil {
625 logger.Errorw("error-disableDevice at FSM stop",
626 log.Fields{"device-id": dh.deviceID, "error": err})
627 // abort: system behavior is just unstable ...
628 return
629 }
630
mpagenko01e726e2020-10-23 09:45:29 +0000631 if dh.deviceReason != "rebooting" {
632 // disable UNI ports/ONU
633 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
634 if dh.pLockStateFsm == nil {
635 dh.createUniLockFsm(true, UniDisableStateDone)
636 } else { //LockStateFSM already init
637 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
638 dh.runUniLockFsm(true)
639 }
640 } else {
641 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
642 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
643 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
644 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
645 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
646 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
647 }
648
649 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
650 "reason": "omci-admin-lock", "device-id": dh.deviceID})
651 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
652 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
653 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
654 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
655 }
656 dh.deviceReason = "omci-admin-lock"
657
658 //stop the device entry which resets the attached omciCC
659 pDevEntry := dh.getOnuDeviceEntry(false)
660 if pDevEntry == nil {
661 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
662 return
663 }
664 _ = pDevEntry.stop(context.TODO(), true) //stop deviceEntry with omciCC reset
mpagenko3af1f032020-06-10 08:53:41 +0000665 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300666 }
667}
668
Himani Chawla6d2ae152020-09-02 13:11:20 +0530669//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530670func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000671 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000672
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000673 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000674 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000675 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000676 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000677 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000678 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000679 dh.runUniLockFsm(false)
680 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300681}
682
Himani Chawla6d2ae152020-09-02 13:11:20 +0530683func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000684 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
685
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000686 pDevEntry := dh.getOnuDeviceEntry(true)
687 if pDevEntry == nil {
688 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
689 return
690 }
691 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000692 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
693 dh.reconciling = false
694 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000695 }
Himani Chawla4d908332020-08-31 12:30:20 +0530696 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000697 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
698 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
699 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
700 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530701 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000702}
703
Himani Chawla6d2ae152020-09-02 13:11:20 +0530704func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000705 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
706
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000707 pDevEntry := dh.getOnuDeviceEntry(true)
708 if pDevEntry == nil {
709 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
710 return
711 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000712
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000713 dh.pOnuTP.lockTpProcMutex()
714 defer dh.pOnuTP.unlockTpProcMutex()
715
716 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000717 // deadline context to ensure completion of background routines waited for
718 //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 +0530719 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000720 dctx, cancel := context.WithDeadline(context.Background(), deadline)
721
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000722 dh.pOnuTP.resetTpProcessingErrorIndication()
723
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000724 var wg sync.WaitGroup
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000725 wg.Add(1) // for the 1 go routine to finish
726 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPath, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000727 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000728
729 if err := dh.pOnuTP.getTpProcessingErrorIndication(); err != nil {
730 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
731 }
732 }
733}
734
735func (dh *deviceHandler) reconcileDeviceFlowConfig() {
736 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
737
738 pDevEntry := dh.getOnuDeviceEntry(true)
739 if pDevEntry == nil {
740 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000741 return
742 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000743 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
744 var uniPort *onuUniPort
745 var exist bool
746 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
747 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000748 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000749 return
750 }
751 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000752 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
753 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000754 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000755 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
756 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
757 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000758 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
759 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000760 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000761 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
762 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
763 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000764 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
765 }
766 }
767 }
768 }
769}
770
771func (dh *deviceHandler) reconcileMetrics() {
772 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
773
774 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000775 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000776}
777
Himani Chawla6d2ae152020-09-02 13:11:20 +0530778func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000779 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000780
781 pDevEntry := dh.getOnuDeviceEntry(true)
782 if pDevEntry == nil {
783 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
784 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000785 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000786 pDevEntry.lockOnuKVStoreMutex()
787 defer pDevEntry.unlockOnuKVStoreMutex()
788
789 // deadline context to ensure completion of background routines waited for
790 //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 +0530791 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 dctx, cancel := context.WithDeadline(context.Background(), deadline)
793
794 pDevEntry.resetKvProcessingErrorIndication()
795
796 var wg sync.WaitGroup
797 wg.Add(1) // for the 1 go routine to finish
798 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000799 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000800
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000801 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000802 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000803}
804
Himani Chawla6d2ae152020-09-02 13:11:20 +0530805func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000806 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300807 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000808 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300810 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530811 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530812 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
813 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
814 return err
815 }
mpagenko01e726e2020-10-23 09:45:29 +0000816
817 //transfer the possibly modified logical uni port state
818 dh.disableUniPortStateUpdate()
819
Andrea Campanellabef4e542020-10-22 11:01:28 +0200820 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000821 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200822 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300823 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000824 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000825 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300826 return err
827 }
Andrea Campanellabef4e542020-10-22 11:01:28 +0200828 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000829 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000830 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300831 return err
832 }
mpagenko01e726e2020-10-23 09:45:29 +0000833 dh.deviceReason = "rebooting"
ozgecanetsiae11479f2020-07-06 09:44:47 +0300834 return nil
835}
836
Himani Chawla6d2ae152020-09-02 13:11:20 +0530837// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000838// #####################################################################################
839
840// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530841// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000842
Himani Chawla6d2ae152020-09-02 13:11:20 +0530843func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000844 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})
845}
846
847// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530848func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000849
850 logger.Debug("doStateInit-started")
851 var err error
852
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000853 // populate what we know. rest comes later after mib sync
854 dh.device.Root = false
855 dh.device.Vendor = "OpenONU"
856 dh.device.Model = "go"
857 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000858 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000859
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000860 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000861
862 if !dh.reconciling {
Himani Chawla4d908332020-08-31 12:30:20 +0530863 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000864 } else {
865 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
866 log.Fields{"device-id": dh.deviceID})
867 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000868
Himani Chawla4d908332020-08-31 12:30:20 +0530869 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000870 dh.ponPortNumber = dh.device.ParentPortNo
871
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000872 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
873 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
874 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000875 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000876 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530877 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000878
879 /*
880 self._pon = PonPort.create(self, self._pon_port_number)
881 self._pon.add_peer(self.parent_id, self._pon_port_number)
882 self.logger.debug('adding-pon-port-to-agent',
883 type=self._pon.get_port().type,
884 admin_state=self._pon.get_port().admin_state,
885 oper_status=self._pon.get_port().oper_status,
886 )
887 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000888 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000889 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000890 var ponPortNo uint32 = 1
891 if dh.ponPortNumber != 0 {
892 ponPortNo = dh.ponPortNumber
893 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000894
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000895 pPonPort := &voltha.Port{
896 PortNo: ponPortNo,
897 Label: fmt.Sprintf("pon-%d", ponPortNo),
898 Type: voltha.Port_PON_ONU,
899 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530900 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000901 PortNo: ponPortNo}}, // Peer port is parent's port number
902 }
903 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
904 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
905 e.Cancel(err)
906 return
907 }
908 } else {
909 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000910 }
911 logger.Debug("doStateInit-done")
912}
913
914// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530915func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000916
917 logger.Debug("postInit-started")
918 var err error
919 /*
920 dh.Client = oop.NewOpenoltClient(dh.clientCon)
921 dh.pTransitionMap.Handle(ctx, GrpcConnected)
922 return nil
923 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530924 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
925 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000926 e.Cancel(err)
927 return
928 }
929
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000930 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530931 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000932 // reconcilement will be continued after mib download is done
933 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000934 /*
935 ############################################################################
936 # Setup Alarm handler
937 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
938 device.serial_number)
939 ############################################################################
940 # Setup PM configuration for this device
941 # Pass in ONU specific options
942 kwargs = {
943 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
944 'heartbeat': self.heartbeat,
945 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
946 }
947 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
948 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
949 self.logical_device_id, device.serial_number,
950 grouped=True, freq_override=False, **kwargs)
951 pm_config = self._pm_metrics.make_proto()
952 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
953 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
954 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
955
956 # Note, ONU ID and UNI intf set in add_uni_port method
957 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
958 ani_ports=[self._pon])
959
960 # Code to Run OMCI Test Action
961 kwargs_omci_test_action = {
962 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
963 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
964 }
965 serial_number = device.serial_number
966 self._test_request = OmciTestRequest(self.core_proxy,
967 self.omci_agent, self.device_id,
968 AniG, serial_number,
969 self.logical_device_id,
970 exclusive=False,
971 **kwargs_omci_test_action)
972
973 self.enabled = True
974 else:
975 self.logger.info('onu-already-activated')
976 */
977 logger.Debug("postInit-done")
978}
979
980// doStateConnected get the device info and update to voltha core
981// for comparison of the original method (not that easy to uncomment): compare here:
982// voltha-openolt-adapter/adaptercore/device_handler.go
983// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +0530984func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000985
986 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530987 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000988 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000989 logger.Debug("doStateConnected-done")
990}
991
992// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530993func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000994
995 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +0530996 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000998 logger.Debug("doStateUp-done")
999
1000 /*
1001 // Synchronous call to update device state - this method is run in its own go routine
1002 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1003 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001004 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 +00001005 return err
1006 }
1007 return nil
1008 */
1009}
1010
1011// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301012func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001013
1014 logger.Debug("doStateDown-started")
1015 var err error
1016
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001017 device := dh.device
1018 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001019 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001020 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001021 e.Cancel(err)
1022 return
1023 }
1024
1025 cloned := proto.Clone(device).(*voltha.Device)
1026 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1027 /*
1028 // Update the all ports state on that device to disable
1029 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001030 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001031 return er
1032 }
1033
1034 //Update the device oper state and connection status
1035 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1036 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1037 dh.device = cloned
1038
1039 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001040 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001041 return er
1042 }
1043
1044 //get the child device for the parent device
1045 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1046 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001047 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001048 return err
1049 }
1050 for _, onuDevice := range onuDevices.Items {
1051
1052 // Update onu state as down in onu adapter
1053 onuInd := oop.OnuIndication{}
1054 onuInd.OperState = "down"
1055 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1056 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1057 if er != nil {
1058 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001059 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001060 //Do not return here and continue to process other ONUs
1061 }
1062 }
1063 // * Discovered ONUs entries need to be cleared , since after OLT
1064 // is up, it starts sending discovery indications again* /
1065 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001066 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001067 return nil
1068 */
Himani Chawla4d908332020-08-31 12:30:20 +05301069 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001070 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001071 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001072}
1073
Himani Chawla6d2ae152020-09-02 13:11:20 +05301074// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001075// #################################################################################
1076
1077// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301078// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001079
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001080//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301081func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001082 dh.lockDevice.RLock()
1083 pOnuDeviceEntry := dh.pOnuOmciDevice
1084 if aWait && pOnuDeviceEntry == nil {
1085 //keep the read sema short to allow for subsequent write
1086 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001087 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001088 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1089 // so it might be needed to wait here for that event with some timeout
1090 select {
1091 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001092 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001093 return nil
1094 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001095 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001096 // if written now, we can return the written value without sema
1097 return dh.pOnuOmciDevice
1098 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001099 }
mpagenko3af1f032020-06-10 08:53:41 +00001100 dh.lockDevice.RUnlock()
1101 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001102}
1103
Himani Chawla6d2ae152020-09-02 13:11:20 +05301104//setOnuDeviceEntry sets the ONU device entry within the handler
1105func (dh *deviceHandler) setOnuDeviceEntry(
1106 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001107 dh.lockDevice.Lock()
1108 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001109 dh.pOnuOmciDevice = apDeviceEntry
1110 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001111}
1112
Himani Chawla6d2ae152020-09-02 13:11:20 +05301113//addOnuDeviceEntry creates a new ONU device or returns the existing
1114func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001115 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116
Himani Chawla6d2ae152020-09-02 13:11:20 +05301117 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001118 if deviceEntry == nil {
1119 /* costum_me_map in python code seems always to be None,
1120 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1121 /* also no 'clock' argument - usage open ...*/
1122 /* and no alarm_db yet (oo.alarm_db) */
Himani Chawla6d2ae152020-09-02 13:11:20 +05301123 deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
mpagenkoaf801632020-07-03 10:00:42 +00001124 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001125 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001126 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
mpagenko01e726e2020-10-23 09:45:29 +00001127 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001128 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301129 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001130 // fire deviceEntry ready event to spread to possibly waiting processing
1131 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +00001132 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 } else {
divyadesai4d299552020-08-18 07:13:49 +00001134 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135 }
1136 // might be updated with some error handling !!!
1137 return nil
1138}
1139
1140// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301141func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001142 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1143 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1144
1145 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001147 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001148 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1149 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001150 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1151 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1152 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1153 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1154 }
1155 } else {
1156 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1157 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001158 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001159 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1160 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1161 // 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 +00001162 // 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 +00001163 // so let's just try to keep it simple ...
1164 /*
1165 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1166 if err != nil || device == nil {
1167 //TODO: needs to handle error scenarios
1168 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1169 return errors.New("Voltha Device not found")
1170 }
1171 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001172
Himani Chawla6d2ae152020-09-02 13:11:20 +05301173 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001174 if pDevEntry != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301175 if err := pDevEntry.start(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301176 return err
1177 }
mpagenko3af1f032020-06-10 08:53:41 +00001178 } else {
divyadesai4d299552020-08-18 07:13:49 +00001179 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001180 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001181 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001182 if !dh.reconciling {
1183 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
1184 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1185 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
1186 }
1187 } else {
1188 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
1189 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001190 }
mpagenko3af1f032020-06-10 08:53:41 +00001191 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001192
1193 /* this might be a good time for Omci Verify message? */
1194 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301195 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001196 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001197 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301198 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001199
1200 /* give the handler some time here to wait for the OMCi verification result
1201 after Timeout start and try MibUpload FSM anyway
1202 (to prevent stopping on just not supported OMCI verification from ONU) */
1203 select {
1204 case <-time.After(2 * time.Second):
1205 logger.Warn("omci start-verification timed out (continue normal)")
1206 case testresult := <-verifyExec:
1207 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1208 }
1209
1210 /* In py code it looks earlier (on activate ..)
1211 # Code to Run OMCI Test Action
1212 kwargs_omci_test_action = {
1213 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1214 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1215 }
1216 serial_number = device.serial_number
1217 self._test_request = OmciTestRequest(self.core_proxy,
1218 self.omci_agent, self.device_id,
1219 AniG, serial_number,
1220 self.logical_device_id,
1221 exclusive=False,
1222 **kwargs_omci_test_action)
1223 ...
1224 # Start test requests after a brief pause
1225 if not self._test_request_started:
1226 self._test_request_started = True
1227 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1228 reactor.callLater(tststart, self._test_request.start_collector)
1229
1230 */
1231 /* which is then: in omci_test_request.py : */
1232 /*
1233 def start_collector(self, callback=None):
1234 """
1235 Start the collection loop for an adapter if the frequency > 0
1236
1237 :param callback: (callable) Function to call to collect PM data
1238 """
1239 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1240 if callback is None:
1241 callback = self.perform_test_omci
1242
1243 if self.lc is None:
1244 self.lc = LoopingCall(callback)
1245
1246 if self.default_freq > 0:
1247 self.lc.start(interval=self.default_freq / 10)
1248
1249 def perform_test_omci(self):
1250 """
1251 Perform the initial test request
1252 """
1253 ani_g_entities = self._device.configuration.ani_g_entities
1254 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1255 is not None else None
1256 self._entity_id = ani_g_entities_ids[0]
1257 self.logger.info('perform-test', entity_class=self._entity_class,
1258 entity_id=self._entity_id)
1259 try:
1260 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1261 result = yield self._device.omci_cc.send(frame)
1262 if not result.fields['omci_message'].fields['success_code']:
1263 self.logger.info('Self-Test Submitted Successfully',
1264 code=result.fields[
1265 'omci_message'].fields['success_code'])
1266 else:
1267 raise TestFailure('Test Failure: {}'.format(
1268 result.fields['omci_message'].fields['success_code']))
1269 except TimeoutError as e:
1270 self.deferred.errback(failure.Failure(e))
1271
1272 except Exception as e:
1273 self.logger.exception('perform-test-Error', e=e,
1274 class_id=self._entity_class,
1275 entity_id=self._entity_id)
1276 self.deferred.errback(failure.Failure(e))
1277
1278 */
1279
1280 // PM related heartbeat??? !!!TODO....
1281 //self._heartbeat.enabled = True
1282
mpagenko1cc3cb42020-07-27 15:24:38 +00001283 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1284 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1285 * 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 +05301286 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001287 */
1288 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001289 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001290 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001291 if pMibUlFsm.Is(ulStDisabled) {
1292 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001293 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001294 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301295 }
1296 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1297 //Determine ONU status and start/re-start MIB Synchronization tasks
1298 //Determine if this ONU has ever synchronized
1299 if true { //TODO: insert valid check
1300 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001301 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 +00001302 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001303 }
Himani Chawla4d908332020-08-31 12:30:20 +05301304 } else {
1305 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001306 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 +00001307 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301308 }
1309 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1310 //Examine the MIB Data Sync
1311 // callbacks to be handled:
1312 // Event(ulEvSuccess)
1313 // Event(ulEvTimeout)
1314 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001315 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001316 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001317 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001318 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001319 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001320 }
1321 } else {
divyadesai4d299552020-08-18 07:13:49 +00001322 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001323 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001324 }
1325 return nil
1326}
1327
Himani Chawla6d2ae152020-09-02 13:11:20 +05301328func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001329 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1330 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001331 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001332 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1333 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1334 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1335 if err := dh.resetFsms(); err != nil {
1336 logger.Errorw("error-updateInterface at FSM stop",
1337 log.Fields{"device-id": dh.deviceID, "error": err})
1338 // abort: system behavior is just unstable ...
1339 return err
1340 }
1341
1342 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1343 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1344 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301345 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001346 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001347 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001348 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001349 }
mpagenko900ee4b2020-10-12 11:56:34 +00001350 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001351
1352 //TODO!!! remove existing traffic profiles
1353 /* from py code, if TP's exist, remove them - not yet implemented
1354 self._tp = dict()
1355 # Let TP download happen again
1356 for uni_id in self._tp_service_specific_task:
1357 self._tp_service_specific_task[uni_id].clear()
1358 for uni_id in self._tech_profile_download_done:
1359 self._tech_profile_download_done[uni_id].clear()
1360 */
1361
1362 dh.disableUniPortStateUpdate()
1363
1364 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001365 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001366 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001367 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001368 // abort: system behavior is just unstable ...
1369 return err
1370 }
1371 dh.deviceReason = "stopping-openomci"
1372
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001373 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1374 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001375 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1376 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001377 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001378 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001379 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001380 // abort: system behavior is just unstable ...
1381 return err
1382 }
1383 } else {
divyadesai4d299552020-08-18 07:13:49 +00001384 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001385 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001386 return nil
1387}
1388
mpagenko900ee4b2020-10-12 11:56:34 +00001389func (dh *deviceHandler) resetFsms() error {
1390 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1391 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1392 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1393 // and using the stop/reset event should never harm
1394
1395 pDevEntry := dh.getOnuDeviceEntry(false)
1396 if pDevEntry == nil {
1397 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1398 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1399 }
1400
1401 //the MibSync FSM might be active all the ONU-active time,
1402 // hence it must be stopped unconditionally
1403 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1404 if pMibUlFsm != nil {
1405 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1406 }
1407 //MibDownload may run
1408 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1409 if pMibDlFsm != nil {
1410 _ = pMibDlFsm.Event(dlEvReset)
1411 }
1412 //port lock/unlock FSM's may be active
1413 if dh.pUnlockStateFsm != nil {
1414 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1415 }
1416 if dh.pLockStateFsm != nil {
1417 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1418 }
1419 //techProfile related PonAniConfigFsm FSM may be active
1420 if dh.pOnuTP != nil {
1421 // should always be the case here
1422 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1423 if dh.pOnuTP.pAniConfigFsm != nil {
1424 _ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1425 }
1426 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001427 // reset the possibly existing VlanConfigFsm
1428 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1429 //VlanFilterFsm exists and was already started
1430 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1431 if pVlanFilterStatemachine != nil {
1432 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1433 }
1434 }
1435 }
1436 }
1437 //TODO!!! care about PM/Alarm processing once started
1438 return nil
1439}
1440
Himani Chawla6d2ae152020-09-02 13:11:20 +05301441func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301442 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
1443 if !dh.reconciling {
1444 //initiate DevStateUpdate
1445 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1446 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1447 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
1448 "device-id": dh.deviceID, "error": err})
1449 } else {
mpagenko01e726e2020-10-23 09:45:29 +00001450 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301451 }
1452 } else {
1453 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
1454 log.Fields{"device-id": dh.deviceID})
1455 }
1456 //set internal state anyway - as it was done
1457 dh.deviceReason = "discovery-mibsync-complete"
1458
1459 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301460 pDevEntry := dh.getOnuDeviceEntry(false)
1461 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301462 for _, mgmtEntityID := range unigInstKeys {
1463 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1464 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301465 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301466 i++
1467 }
1468 } else {
1469 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1470 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301471 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301472 for _, mgmtEntityID := range veipInstKeys {
1473 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1474 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301475 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301476 i++
1477 }
1478 } else {
1479 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1480 }
1481 if i == 0 {
1482 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1483 }
1484
1485 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1486 * left the code here as comment in case such processing should prove needed unexpectedly
1487 // Init Uni Ports to Admin locked state
1488 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1489 // *** should generate UniLockStateDone event *****
1490 if dh.pLockStateFsm == nil {
1491 dh.createUniLockFsm(true, UniLockStateDone)
1492 } else { //LockStateFSM already init
1493 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1494 dh.runUniLockFsm(true)
1495 }
1496 }
1497 case UniLockStateDone:
1498 {
1499 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
1500 * lockState processing commented out
1501 */
1502 /* Mib download procedure -
1503 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1504 */
1505 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1506 if pMibDlFsm != nil {
1507 if pMibDlFsm.Is(dlStDisabled) {
1508 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001509 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301510 // maybe try a FSM reset and then again ... - TODO!!!
1511 } else {
1512 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1513 // maybe use more specific states here for the specific download steps ...
1514 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001515 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301516 } else {
1517 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1518 //Begin MIB data download (running autonomously)
1519 }
1520 }
1521 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001522 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001523 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301524 // maybe try a FSM reset and then again ... - TODO!!!
1525 }
1526 /***** Mib download started */
1527 } else {
1528 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1529 }
1530}
1531
Himani Chawla6d2ae152020-09-02 13:11:20 +05301532func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301533 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
1534 //initiate DevStateUpdate
1535 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001536 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1537 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301538 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1539 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1540 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1541 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1542 } else {
1543 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1544 }
1545 } else {
1546 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1547 log.Fields{"device-id": dh.deviceID})
1548 }
1549 if !dh.reconciling {
1550 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1551 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1552 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
1553 log.Fields{"device-id": dh.deviceID, "error": err})
1554 } else {
1555 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
1556 }
1557 } else {
1558 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
1559 log.Fields{"device-id": dh.deviceID})
1560 }
1561 //set internal state anyway - as it was done
1562 dh.deviceReason = "initial-mib-downloaded"
1563 // *** should generate UniUnlockStateDone event *****
1564 if dh.pUnlockStateFsm == nil {
1565 dh.createUniLockFsm(false, UniUnlockStateDone)
1566 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301567 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301568 dh.runUniLockFsm(false)
1569 }
1570}
1571
Himani Chawla6d2ae152020-09-02 13:11:20 +05301572func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001573 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301574
1575 if !dh.reconciling {
1576 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1577 raisedTs := time.Now().UnixNano()
1578 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1579 } else {
1580 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1581 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301582 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001583 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301584 }
1585}
1586
mpagenko900ee4b2020-10-12 11:56:34 +00001587func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1588 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1589 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1590 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1591 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1592 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1593 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1594 }
1595
1596 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1597 "reason": "omci-admin-lock", "device-id": dh.deviceID})
1598 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1599 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
1600 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1601 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1602 }
1603 dh.deviceReason = "omci-admin-lock"
1604
1605 //transfer the modified logical uni port state
1606 dh.disableUniPortStateUpdate()
1607
1608 //stop the device entry which resets the attached omciCC
1609 pDevEntry := dh.getOnuDeviceEntry(false)
1610 if pDevEntry == nil {
1611 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1612 return
1613 }
1614 _ = pDevEntry.stop(context.TODO(), true) //stop deviceEntry with omciCC reset
mpagenko900ee4b2020-10-12 11:56:34 +00001615}
1616
1617func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1618 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1619 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1620 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1621 voltha.OperStatus_ACTIVE); err != nil {
1622 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1623 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1624 }
1625
1626 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
1627 "reason": "onu-reenabled", "device-id": dh.deviceID})
1628 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
1629 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "onu-reenabled"); err != nil {
1630 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1631 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
1632 }
1633 dh.deviceReason = "onu-reenabled"
1634
1635 //transfer the modified logical uni port state
1636 dh.enableUniPortStateUpdate()
1637}
1638
Himani Chawla6d2ae152020-09-02 13:11:20 +05301639func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301640 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1641 // attention: the device reason update is done based on ONU-UNI-Port related activity
1642 // - which may cause some inconsistency
1643 if dh.deviceReason != "tech-profile-config-download-success" {
1644 // which may be the case from some previous actvity on another UNI Port of the ONU
1645 if !dh.reconciling {
1646 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1647 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1648 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
1649 log.Fields{"device-id": dh.deviceID, "error": err})
1650 } else {
1651 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
1652 log.Fields{"device-id": dh.deviceID})
1653 }
1654 } else {
1655 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
1656 log.Fields{"device-id": dh.deviceID})
1657 }
1658 //set internal state anyway - as it was done
1659 dh.deviceReason = "tech-profile-config-download-success"
1660 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001661 if dh.reconciling {
1662 go dh.reconcileDeviceFlowConfig()
1663 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301664}
1665
Himani Chawla6d2ae152020-09-02 13:11:20 +05301666func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301667 logger.Debugw("OmciVlanFilterDone event received",
1668 log.Fields{"device-id": dh.deviceID})
1669 // attention: the device reason update is done based on ONU-UNI-Port related activity
1670 // - which may cause some inconsistency
1671 // yield self.core_proxy.device_reason_update(self.device_id, 'omci-flows-pushed')
1672
1673 if dh.deviceReason != "omci-flows-pushed" {
1674 // which may be the case from some previous actvity on another UNI Port of the ONU
1675 // or even some previous flow add activity on the same port
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001676 if !dh.reconciling {
1677 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
1678 logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
1679 log.Fields{"device-id": dh.deviceID, "error": err})
1680 } else {
1681 logger.Infow("updated dev reason to ''omci-flows-pushed'",
1682 log.Fields{"device-id": dh.deviceID})
1683 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301684 } else {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001685 logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to omci-flows-pushed",
Himani Chawla26e555c2020-08-31 12:30:20 +05301686 log.Fields{"device-id": dh.deviceID})
1687 }
1688 //set internal state anyway - as it was done
1689 dh.deviceReason = "omci-flows-pushed"
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001690
1691 if dh.reconciling {
1692 go dh.reconcileMetrics()
1693 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301694 }
1695}
1696
Himani Chawla6d2ae152020-09-02 13:11:20 +05301697//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1698func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301699 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001700 case MibDatabaseSync:
1701 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301702 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001703 }
1704 case MibDownloadDone:
1705 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301706 dh.processMibDownloadDoneEvent(devEvent)
1707
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001708 }
1709 case UniUnlockStateDone:
1710 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301711 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001712
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001713 }
mpagenko900ee4b2020-10-12 11:56:34 +00001714 case UniEnableStateDone:
1715 {
1716 dh.processUniEnableStateDoneEvent(devEvent)
1717
1718 }
1719 case UniDisableStateDone:
1720 {
1721 dh.processUniDisableStateDoneEvent(devEvent)
1722
1723 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001724 case OmciAniConfigDone:
1725 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301726 dh.processOmciAniConfigDoneEvent(devEvent)
1727
mpagenko3dbcdd22020-07-22 07:38:45 +00001728 }
mpagenkodff5dda2020-08-28 11:52:01 +00001729 case OmciVlanFilterDone:
1730 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301731 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001732
mpagenkodff5dda2020-08-28 11:52:01 +00001733 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001734 default:
1735 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001736 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001737 }
1738 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001739}
1740
Himani Chawla6d2ae152020-09-02 13:11:20 +05301741func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001742 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301743 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301744 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001745 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301746 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001747 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301748 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301749 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001750 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301751 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001752 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001753 //store UniPort with the System-PortNumber key
1754 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001755 if !dh.reconciling {
1756 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301757 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001758 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1759 } //error logging already within UniPort method
1760 } else {
1761 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1762 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001763 }
1764 }
1765}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001766
mpagenko3af1f032020-06-10 08:53:41 +00001767// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301768func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001769 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301770 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001771 // with following remark:
1772 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1773 // # load on the core
1774
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001775 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001776
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001777 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001778 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301779 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001780 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301781 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001782 if !dh.reconciling {
1783 //maybe also use getter functions on uniPort - perhaps later ...
1784 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1785 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001786 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001787 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1788 }
mpagenko3af1f032020-06-10 08:53:41 +00001789 }
1790 }
1791}
1792
1793// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301794func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001795 // compare enableUniPortStateUpdate() above
1796 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1797 for uniNo, uniPort := range dh.uniEntityMap {
1798 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301799 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001800 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301801 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001802 //maybe also use getter functions on uniPort - perhaps later ...
1803 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001804 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001805 }
1806}
1807
1808// ONU_Active/Inactive announcement on system KAFKA bus
1809// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301810func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001811 var de voltha.DeviceEvent
1812 eventContext := make(map[string]string)
1813 //Populating event context
1814 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301815 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001816 if err != nil || parentDevice == nil {
1817 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301818 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001819 }
1820 oltSerialNumber := parentDevice.SerialNumber
1821
1822 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1823 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1824 eventContext["serial-number"] = dh.device.SerialNumber
1825 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301826 eventContext["device_id"] = aDeviceID
1827 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001828 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001829 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001830
1831 /* Populating device event body */
1832 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301833 de.ResourceId = aDeviceID
1834 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001835 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1836 de.Description = fmt.Sprintf("%s Event - %s - %s",
1837 cEventObjectType, cOnuActivatedEvent, "Raised")
1838 } else {
1839 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1840 de.Description = fmt.Sprintf("%s Event - %s - %s",
1841 cEventObjectType, cOnuActivatedEvent, "Cleared")
1842 }
1843 /* Send event to KAFKA */
1844 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1845 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301846 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001847 }
1848 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301849 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001850}
1851
Himani Chawla4d908332020-08-31 12:30:20 +05301852// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301853func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001854 chLSFsm := make(chan Message, 2048)
1855 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301856 if aAdminState {
divyadesai4d299552020-08-18 07:13:49 +00001857 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001858 sFsmName = "LockStateFSM"
1859 } else {
divyadesai4d299552020-08-18 07:13:49 +00001860 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001861 sFsmName = "UnLockStateFSM"
1862 }
mpagenko3af1f032020-06-10 08:53:41 +00001863
Himani Chawla6d2ae152020-09-02 13:11:20 +05301864 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001865 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001866 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001867 return
1868 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301869 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001870 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001871 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301872 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001873 dh.pLockStateFsm = pLSFsm
1874 } else {
1875 dh.pUnlockStateFsm = pLSFsm
1876 }
1877 dh.runUniLockFsm(aAdminState)
1878 } else {
divyadesai4d299552020-08-18 07:13:49 +00001879 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001880 }
1881}
1882
1883// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301884func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001885 /* Uni Port lock/unlock procedure -
1886 ***** should run via 'adminDone' state and generate the argument requested event *****
1887 */
1888 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301889 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001890 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1891 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1892 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001893 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301894 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001895 }
1896 } else {
1897 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1898 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1899 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001900 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301901 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001902 }
1903 }
1904 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001905 if pLSStatemachine.Is(uniStDisabled) {
1906 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001907 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1908 // maybe try a FSM reset and then again ... - TODO!!!
1909 } else {
1910 /***** LockStateFSM started */
1911 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001912 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001913 }
1914 } else {
1915 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001916 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001917 // maybe try a FSM reset and then again ... - TODO!!!
1918 }
1919 } else {
divyadesai4d299552020-08-18 07:13:49 +00001920 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001921 // maybe try a FSM reset and then again ... - TODO!!!
1922 }
1923}
1924
Himani Chawla6d2ae152020-09-02 13:11:20 +05301925//setBackend provides a DB backend for the specified path on the existing KV client
1926func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00001927 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1928 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001929 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001930 kvbackend := &db.Backend{
1931 Client: dh.pOpenOnuAc.kvClient,
1932 StoreType: dh.pOpenOnuAc.KVStoreType,
1933 /* address config update acc. to [VOL-2736] */
1934 Address: addr,
1935 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1936 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001937
mpagenkoaf801632020-07-03 10:00:42 +00001938 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001939}
Himani Chawla6d2ae152020-09-02 13:11:20 +05301940func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05301941 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00001942
mpagenkodff5dda2020-08-28 11:52:01 +00001943 for _, field := range flow.GetOfbFields(apFlowItem) {
1944 switch field.Type {
1945 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
1946 {
mpagenko01e726e2020-10-23 09:45:29 +00001947 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001948 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
1949 }
mpagenko01e726e2020-10-23 09:45:29 +00001950 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00001951 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
1952 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301953 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00001954 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301955 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
1956 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00001957 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
1958 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00001959 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
1960 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301961 return
mpagenkodff5dda2020-08-28 11:52:01 +00001962 }
1963 }
mpagenko01e726e2020-10-23 09:45:29 +00001964 */
mpagenkodff5dda2020-08-28 11:52:01 +00001965 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
1966 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301967 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00001968 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05301969 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00001970 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301971 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00001972 }
mpagenko01e726e2020-10-23 09:45:29 +00001973 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301974 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00001975 }
1976 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
1977 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301978 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00001979 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001980 "PCP": loAddPcp})
1981 }
1982 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
1983 {
mpagenko01e726e2020-10-23 09:45:29 +00001984 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001985 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
1986 }
1987 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
1988 {
mpagenko01e726e2020-10-23 09:45:29 +00001989 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001990 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
1991 }
1992 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
1993 {
mpagenko01e726e2020-10-23 09:45:29 +00001994 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001995 "IPv4-DST": field.GetIpv4Dst()})
1996 }
1997 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
1998 {
mpagenko01e726e2020-10-23 09:45:29 +00001999 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002000 "IPv4-SRC": field.GetIpv4Src()})
2001 }
2002 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2003 {
mpagenko01e726e2020-10-23 09:45:29 +00002004 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002005 "Metadata": field.GetTableMetadata()})
2006 }
2007 /*
2008 default:
2009 {
2010 //all other entires ignored
2011 }
2012 */
2013 }
2014 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302015}
mpagenkodff5dda2020-08-28 11:52:01 +00002016
Himani Chawla6d2ae152020-09-02 13:11:20 +05302017func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002018 for _, action := range flow.GetActions(apFlowItem) {
2019 switch action.Type {
2020 /* not used:
2021 case of.OfpActionType_OFPAT_OUTPUT:
2022 {
mpagenko01e726e2020-10-23 09:45:29 +00002023 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002024 "Output": action.GetOutput()})
2025 }
2026 */
2027 case of.OfpActionType_OFPAT_PUSH_VLAN:
2028 {
mpagenko01e726e2020-10-23 09:45:29 +00002029 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002030 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2031 }
2032 case of.OfpActionType_OFPAT_SET_FIELD:
2033 {
2034 pActionSetField := action.GetSetField()
2035 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00002036 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002037 "OxcmClass": pActionSetField.Field.OxmClass})
2038 }
2039 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302040 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002041 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302042 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002043 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302044 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002045 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302046 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002047 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002048 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002049 "Type": pActionSetField.Field.GetOfbField().Type})
2050 }
2051 }
2052 /*
2053 default:
2054 {
2055 //all other entires ignored
2056 }
2057 */
2058 }
2059 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302060}
2061
2062//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302063func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302064 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2065 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2066 var loAddPcp, loSetPcp uint8
2067 var loIPProto uint32
2068 /* the TechProfileId is part of the flow Metadata - compare also comment within
2069 * OLT-Adapter:openolt_flowmgr.go
2070 * Metadata 8 bytes:
2071 * Most Significant 2 Bytes = Inner VLAN
2072 * Next 2 Bytes = Tech Profile ID(TPID)
2073 * Least Significant 4 Bytes = Port ID
2074 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2075 * subscriber related flows.
2076 */
2077
2078 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2079 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002080 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302081 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002082 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302083 }
2084 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002085 loCookie := apFlowItem.GetCookie()
2086 loCookieSlice := []uint64{loCookie}
2087 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2088 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302089
2090 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002091 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302092 if loIPProto == 2 {
2093 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2094 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002095 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2096 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302097 return nil
2098 }
mpagenko01e726e2020-10-23 09:45:29 +00002099 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302100 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002101
2102 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002103 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002104 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2105 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2106 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2107 //TODO!!: Use DeviceId within the error response to rwCore
2108 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002109 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002110 }
2111 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002112 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002113 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2114 } else {
2115 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2116 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2117 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302118 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002119 }
mpagenko01e726e2020-10-23 09:45:29 +00002120 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002121 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302122 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002123 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2124 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002125 }
mpagenko01e726e2020-10-23 09:45:29 +00002126 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
2127 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
2128}
2129
2130//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2131func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2132 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2133 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2134 //no extra check is done on the rule parameters
2135 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2136 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2137 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2138 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
2139 // - some possible 'delete-all' sequence would have be implemented separately (where the cookies are don't care anyway)
2140 loCookie := apFlowItem.GetCookie()
2141 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2142
2143 /* TT related temporary workaround - should not be needed anymore
2144 for _, field := range flow.GetOfbFields(apFlowItem) {
2145 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2146 loIPProto := field.GetIpProto()
2147 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2148 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2149 if loIPProto == 2 {
2150 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2151 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2152 log.Fields{"device-id": dh.deviceID})
2153 return nil
2154 }
2155 }
2156 } //for all OfbFields
2157 */
2158
2159 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2160 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2161 }
2162 logger.Warnw("flow-remove called, but no flow is configured (no VlanConfigFsm)",
2163 log.Fields{"device-id": dh.deviceID})
2164 //but as we regard the flow as not existing = removed we respond just ok
2165 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002166}
2167
Himani Chawla26e555c2020-08-31 12:30:20 +05302168// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002169func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2170 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002171 chVlanFilterFsm := make(chan Message, 2048)
2172
Himani Chawla6d2ae152020-09-02 13:11:20 +05302173 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002174 if pDevEntry == nil {
2175 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302176 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002177 }
2178
2179 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002180 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2181 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002182 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302183 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002184 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2185 if pVlanFilterStatemachine != nil {
2186 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2187 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2188 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302189 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002190 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302191 /***** UniVlanConfigFsm started */
2192 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2193 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2194 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002195 } else {
2196 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2197 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302198 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002199 }
2200 } else {
2201 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2202 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302203 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002204 }
2205 } else {
2206 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2207 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302208 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002209 }
2210 return nil
2211}
2212
2213//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302214func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002215 //TODO!! verify and start pending flow configuration
2216 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2217 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302218 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002219 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2220 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2221 if pVlanFilterStatemachine != nil {
2222 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2223 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2224 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2225 } else {
2226 /***** UniVlanConfigFsm continued */
2227 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2228 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2229 "UniPort": apUniPort.portNo})
2230 }
2231 } else {
2232 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2233 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2234 }
2235 } else {
2236 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2237 "device-id": dh.deviceID})
2238 }
2239
2240 } // else: nothing to do
2241}
2242
2243//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2244// 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 +05302245func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002246 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2247 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2248 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302249 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002250}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002251
2252//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2253//available for potential reconcilement
2254
2255func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2256
2257 if dh.reconciling {
2258 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2259 return nil
2260 }
2261 logger.Debugw("Store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2262
2263 pDevEntry := dh.getOnuDeviceEntry(true)
2264 if pDevEntry == nil {
2265 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2266 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2267 }
2268 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2269
2270 pDevEntry.lockOnuKVStoreMutex()
2271 defer pDevEntry.unlockOnuKVStoreMutex()
2272
2273 // deadline context to ensure completion of background routines waited for
2274 //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 +05302275 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002276 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2277
2278 pDevEntry.resetKvProcessingErrorIndication()
2279 var wg sync.WaitGroup
2280 wg.Add(1) // for the 1 go routine to finish
2281
2282 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002283 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002284
2285 return pDevEntry.getKvProcessingErrorIndication()
2286}
2287
mpagenko01e726e2020-10-23 09:45:29 +00002288func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002289 defer cancel() //ensure termination of context (may be pro forma)
2290 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002291 logger.Debugw("WaitGroup processing completed", log.Fields{
2292 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002293}
2294
2295func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2296 var errStr string = ""
2297 for _, err := range errS {
2298 if err != nil {
2299 errStr = errStr + err.Error() + " "
2300 }
2301 }
2302 if errStr != "" {
2303 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2304 }
2305 return nil
2306}