blob: 8c4642179d217b0f3dcf7e023e37c0a24b8d0be1 [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
Holger Hildebrandt80129db2020-11-23 10:49:32 +000093const (
94 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +000095 drUnset = 0
96 drActivatingOnu = 1
97 drStartingOpenomci = 2
98 drDiscoveryMibsyncComplete = 3
99 drInitialMibDownloaded = 4
100 drTechProfileConfigDownloadSuccess = 5
101 drOmciFlowsPushed = 6
102 drOmciAdminLock = 7
103 drOnuReenabled = 8
104 drStoppingOpenomci = 9
105 drRebooting = 10
106 drOmciFlowsDeleted = 11
107 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000108)
109
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000110var deviceReasonMap = map[uint8]string{
111 drUnset: "unset",
112 drActivatingOnu: "activating-onu",
113 drStartingOpenomci: "starting-openomci",
114 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
115 drInitialMibDownloaded: "initial-mib-downloaded",
116 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
117 drOmciFlowsPushed: "omci-flows-pushed",
118 drOmciAdminLock: "omci-admin-lock",
119 drOnuReenabled: "onu-reenabled",
120 drStoppingOpenomci: "stopping-openomci",
121 drRebooting: "rebooting",
122 drOmciFlowsDeleted: "omci-flows-deleted",
123 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
124}
125
Himani Chawla6d2ae152020-09-02 13:11:20 +0530126//deviceHandler will interact with the ONU ? device.
127type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000128 deviceID string
129 DeviceType string
130 adminState string
131 device *voltha.Device
132 logicalDeviceID string
133 ProxyAddressID string
134 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530135 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000136 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000137
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000138 coreProxy adapterif.CoreProxy
139 AdapterProxy adapterif.AdapterProxy
140 EventProxy adapterif.EventProxy
141
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000142 pOpenOnuAc *OpenONUAC
143 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530144 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000145 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000146 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530147 pOnuTP *onuUniTechProf
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000148 exitChannel chan int
149 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000150 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000151 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530152 pLockStateFsm *lockStateFsm
153 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000154
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155 //flowMgr *OpenOltFlowMgr
156 //eventMgr *OpenOltEventMgr
157 //resourceMgr *rsrcMgr.OpenOltResourceMgr
158
159 //discOnus sync.Map
160 //onus sync.Map
161 //portStats *OpenOltStatisticsMgr
162 //metrics *pmmetrics.PmMetrics
mpagenkofc4f56e2020-11-04 17:17:49 +0000163 stopCollector chan bool
164 stopHeartbeatCheck chan bool
165 activePorts sync.Map
166 uniEntityMap map[uint32]*onuUniPort
167 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
168 reconciling bool
169 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170}
171
Himani Chawla6d2ae152020-09-02 13:11:20 +0530172//newDeviceHandler creates a new device handler
173func newDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
174 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000175 dh.coreProxy = cp
176 dh.AdapterProxy = ap
177 dh.EventProxy = ep
178 cloned := (proto.Clone(device)).(*voltha.Device)
179 dh.deviceID = cloned.Id
180 dh.DeviceType = cloned.Type
181 dh.adminState = "up"
182 dh.device = cloned
183 dh.pOpenOnuAc = adapter
184 dh.exitChannel = make(chan int, 1)
185 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000186 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 dh.stopCollector = make(chan bool, 2)
188 dh.stopHeartbeatCheck = make(chan bool, 2)
189 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
190 dh.activePorts = sync.Map{}
191 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530192 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000193 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000194 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000195 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196
197 // Device related state machine
198 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000199 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000200 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000201 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
202 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
203 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
204 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
205 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 },
207 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000208 "before_event": func(e *fsm.Event) { dh.logStateChange(e) },
209 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(e) },
210 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(e) },
211 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(e) },
212 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
213 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(e) },
214 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(e) },
215 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000216 },
217 )
mpagenkoaf801632020-07-03 10:00:42 +0000218
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219 return &dh
220}
221
Himani Chawla6d2ae152020-09-02 13:11:20 +0530222// start save the device to the data model
223func (dh *deviceHandler) start(ctx context.Context) {
divyadesai4d299552020-08-18 07:13:49 +0000224 logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000225 // Add the initial device to the local model
226 logger.Debug("device-handler-started")
227}
228
Himani Chawla4d908332020-08-31 12:30:20 +0530229/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000232 logger.Debug("stopping-device-handler")
233 dh.exitChannel <- 1
234}
Himani Chawla4d908332020-08-31 12:30:20 +0530235*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236
237// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530238// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240//adoptOrReconcileDevice adopts the OLT device
241func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000242 logger.Debugw("Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000244 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000245 if dh.pDeviceStateFsm.Is(devStNull) {
246 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
248 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000249 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 } else {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000251 logger.Debugw("AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 }
253
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254}
255
Himani Chawla6d2ae152020-09-02 13:11:20 +0530256func (dh *deviceHandler) processInterAdapterOMCIReqMessage(msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530257 msgBody := msg.GetBody()
258 omciMsg := &ic.InterAdapterOmciMessage{}
259 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
260 logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
261 "device-id": dh.deviceID, "error": err})
262 return err
263 }
264
265 //assuming omci message content is hex coded!
266 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
267 logger.Debugw("inter-adapter-recv-omci", log.Fields{
268 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
269 //receive_message(omci_msg.message)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530270 pDevEntry := dh.getOnuDeviceEntry(true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530271 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000272 if pDevEntry.PDevOmciCC != nil {
273 return pDevEntry.PDevOmciCC.receiveMessage(context.TODO(), omciMsg.Message)
274 }
275 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 +0530276 }
277 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000278 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530279}
280
Himani Chawla6d2ae152020-09-02 13:11:20 +0530281func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530282 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000283
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000284 logger.Infow("tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
285
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000286 pDevEntry := dh.getOnuDeviceEntry(true)
287 if pDevEntry == nil {
288 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
289 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
290 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530291 if dh.pOnuTP == nil {
292 //should normally not happen ...
mpagenkoa40e99a2020-11-17 13:50:39 +0000293 logger.Errorw("onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530294 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000295 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530296 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000297 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000298 logger.Errorw("TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000299 "device-state": deviceReasonMap[dh.deviceReason]})
300 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530301 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000302 //previous state test here was just this one, now extended for more states to reject the SetRequest:
303 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
304 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530305
306 msgBody := msg.GetBody()
307 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
308 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
309 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
310 "device-id": dh.deviceID, "error": err})
311 return err
312 }
313
314 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000315 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
316 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530317 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000318 defer dh.pOnuTP.unlockTpProcMutex()
319 pDevEntry.lockOnuKVStoreMutex()
320 defer pDevEntry.unlockOnuKVStoreMutex()
321
322 if techProfMsg.UniId > 255 {
323 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
324 techProfMsg.UniId, dh.deviceID))
325 }
326 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800327 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
328 if err != nil {
329 logger.Errorw("error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
330 return err
331 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000332
Girish Gowdra041dcb32020-11-16 16:54:30 -0800333 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530334 // if there has been some change for some uni TechProfilePath
335 //in order to allow concurrent calls to other dh instances we do not wait for execution here
336 //but doing so we can not indicate problems to the caller (who does what with that then?)
337 //by now we just assume straightforward successful execution
338 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
339 // possible problems to the caller later autonomously
340
341 // deadline context to ensure completion of background routines waited for
342 //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 +0530343 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530344 dctx, cancel := context.WithDeadline(context.Background(), deadline)
345
Girish Gowdra041dcb32020-11-16 16:54:30 -0800346 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000347 pDevEntry.resetKvProcessingErrorIndication()
348
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 var wg sync.WaitGroup
350 wg.Add(2) // for the 2 go routines to finish
351 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000352 go dh.pOnuTP.configureUniTp(dctx, uniID, techProfMsg.Path, &wg)
353 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000354 dh.waitForCompletion(cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000355
Girish Gowdra041dcb32020-11-16 16:54:30 -0800356 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000358 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 return nil
360}
361
Himani Chawla6d2ae152020-09-02 13:11:20 +0530362func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 msg *ic.InterAdapterMessage) error {
364
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000365 logger.Infow("delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
366
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367 pDevEntry := dh.getOnuDeviceEntry(true)
368 if pDevEntry == nil {
369 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
370 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
371 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if dh.pOnuTP == nil {
373 //should normally not happen ...
374 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
375 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 }
378
379 msgBody := msg.GetBody()
380 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
381 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
382 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
383 "device-id": dh.deviceID, "error": err})
384 return err
385 }
386
387 //compare TECH_PROFILE_DOWNLOAD_REQUEST
388 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389 defer dh.pOnuTP.unlockTpProcMutex()
390 pDevEntry.lockOnuKVStoreMutex()
391 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530392
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 if delGemPortMsg.UniId > 255 {
394 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
395 delGemPortMsg.UniId, dh.deviceID))
396 }
397 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800398 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
399 if err != nil {
400 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
401 return err
402 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530403
mpagenkofc4f56e2020-11-04 17:17:49 +0000404 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405
mpagenkofc4f56e2020-11-04 17:17:49 +0000406 // deadline context to ensure completion of background routines waited for
407 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
408 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409
Girish Gowdra041dcb32020-11-16 16:54:30 -0800410 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411
mpagenkofc4f56e2020-11-04 17:17:49 +0000412 var wg sync.WaitGroup
413 wg.Add(1) // for the 1 go routine to finish
mpagenko8b07c1b2020-11-26 10:36:31 +0000414 go dh.pOnuTP.deleteTpResource(dctx, uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000415 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
416 dh.waitForCompletion(cancel, &wg, "GemDelete") //wait for background process to finish
417
Girish Gowdra041dcb32020-11-16 16:54:30 -0800418 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530419}
420
Himani Chawla6d2ae152020-09-02 13:11:20 +0530421func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000424 logger.Infow("delete-tcont-request", log.Fields{"device-id": dh.deviceID})
425
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426 pDevEntry := dh.getOnuDeviceEntry(true)
427 if pDevEntry == nil {
428 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
429 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
430 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 if dh.pOnuTP == nil {
432 //should normally not happen ...
433 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
434 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000435 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530436 }
437
438 msgBody := msg.GetBody()
439 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
440 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
441 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
442 "device-id": dh.deviceID, "error": err})
443 return err
444 }
445
446 //compare TECH_PROFILE_DOWNLOAD_REQUEST
447 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 defer dh.pOnuTP.unlockTpProcMutex()
449 pDevEntry.lockOnuKVStoreMutex()
450 defer pDevEntry.unlockOnuKVStoreMutex()
451
452 if delTcontMsg.UniId > 255 {
453 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
454 delTcontMsg.UniId, dh.deviceID))
455 }
456 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800457 tpPath := delTcontMsg.TpPath
458 tpID, err := GetTpIDFromTpPath(tpPath)
459 if err != nil {
460 logger.Errorw("error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
461 return err
462 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000463
Girish Gowdra041dcb32020-11-16 16:54:30 -0800464 if bTpModify := pDevEntry.updateOnuUniTpPath(uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530465 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530466 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530467 dctx, cancel := context.WithDeadline(context.Background(), deadline)
468
Girish Gowdra041dcb32020-11-16 16:54:30 -0800469 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 pDevEntry.resetKvProcessingErrorIndication()
471
Himani Chawla26e555c2020-08-31 12:30:20 +0530472 var wg sync.WaitGroup
473 wg.Add(2) // for the 2 go routines to finish
mpagenko8b07c1b2020-11-26 10:36:31 +0000474 go dh.pOnuTP.deleteTpResource(dctx, uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 cResourceTcont, delTcontMsg.AllocId, &wg)
476 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000478 dh.waitForCompletion(cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479
Girish Gowdra041dcb32020-11-16 16:54:30 -0800480 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 return nil
483}
484
Himani Chawla6d2ae152020-09-02 13:11:20 +0530485//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000486// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
487// is meant, and then send the unmarshalled omci message to this onu
Himani Chawla6d2ae152020-09-02 13:11:20 +0530488func (dh *deviceHandler) processInterAdapterMessage(msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000489 msgID := msg.Header.Id
490 msgType := msg.Header.Type
491 fromTopic := msg.Header.FromTopic
492 toTopic := msg.Header.ToTopic
493 toDeviceID := msg.Header.ToDeviceId
494 proxyDeviceID := msg.Header.ProxyDeviceId
495 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
496 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
497
498 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000499 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000500 case ic.InterAdapterMessageType_OMCI_REQUEST:
501 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 return dh.processInterAdapterOMCIReqMessage(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000503 }
mpagenkoaf801632020-07-03 10:00:42 +0000504 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
505 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530506 return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000507 }
508 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
509 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530510 return dh.processInterAdapterDeleteGemPortReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000511
mpagenkoaf801632020-07-03 10:00:42 +0000512 }
513 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
514 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 return dh.processInterAdapterDeleteTcontReqMessage(msg)
mpagenkoaf801632020-07-03 10:00:42 +0000516 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000517 default:
518 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000519 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 "msgType": msg.Header.Type, "device-id": dh.deviceID})
521 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000522 }
523 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000524}
525
mpagenkodff5dda2020-08-28 11:52:01 +0000526//FlowUpdateIncremental removes and/or adds the flow changes on a given device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530527func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000528 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
mpagenko01e726e2020-10-23 09:45:29 +0000529 logger.Debugw("FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000530
mpagenko01e726e2020-10-23 09:45:29 +0000531 var retError error = nil
532 //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 +0000533 if apOfFlowChanges.ToRemove != nil {
534 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000535 if flowItem.GetCookie() == 0 {
mpagenko01e726e2020-10-23 09:45:29 +0000536 logger.Warnw("flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
537 "device-id": dh.deviceID})
538 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000539 continue
540 }
541 flowInPort := flow.GetInPort(flowItem)
542 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
mpagenko01e726e2020-10-23 09:45:29 +0000543 logger.Warnw("flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
544 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
545 continue
546 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000547 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000548 //this is some downstream flow, not regarded as error, just ignored
549 logger.Debugw("flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
550 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000551 continue
552 } else {
553 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530554 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000555 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
556 loUniPort = uniPort
557 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000558 logger.Warnw("flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
559 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
560 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
561 flowInPort, dh.deviceID)
562 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000563 }
564 flowOutPort := flow.GetOutPort(flowItem)
mpagenko01e726e2020-10-23 09:45:29 +0000565 logger.Debugw("flow-remove port indications", log.Fields{
566 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000567 "uniPortName": loUniPort.name})
mpagenko01e726e2020-10-23 09:45:29 +0000568 err := dh.removeFlowItemFromUniPort(flowItem, loUniPort)
569 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000570 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000571 logger.Warnw("flow-remove processing error: continuing on checking further flows",
572 log.Fields{"device-id": dh.deviceID, "error": err})
573 retError = err
574 continue
575 //return err
576 } else { // if last setting succeeds, overwrite possibly previously set error
577 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000578 }
579 }
580 }
581 }
mpagenko01e726e2020-10-23 09:45:29 +0000582 if apOfFlowChanges.ToAdd != nil {
583 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
584 if flowItem.GetCookie() == 0 {
585 logger.Debugw("incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
586 "device-id": dh.deviceID})
587 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
588 continue
589 }
590 flowInPort := flow.GetInPort(flowItem)
591 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
592 logger.Warnw("flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
593 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
594 continue
595 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
596 } else if flowInPort == dh.ponPortNumber {
597 //this is some downstream flow
598 logger.Debugw("flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
599 "device-id": dh.deviceID, "inPort": flowInPort})
600 continue
601 } else {
602 // this is the relevant upstream flow
603 var loUniPort *onuUniPort
604 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
605 loUniPort = uniPort
606 } else {
607 logger.Warnw("flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
608 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
609 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
610 flowInPort, dh.deviceID)
611 continue
612 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
613 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000614 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
615 // if not, we just throw some error here to have an indication about that, if we really need to support that
616 // then we would need to create some means to activate the internal stored flows
617 // after the device gets active automatically (and still with its dependency to the TechProfile)
618 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
619 // also abort for the other still possible flows here
620 if !dh.ReadyForSpecificOmciConfig {
mpagenkoa40e99a2020-11-17 13:50:39 +0000621 logger.Errorw("flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000622 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000623 return fmt.Errorf("improper device state on device %s", dh.deviceID)
624 }
625
mpagenko01e726e2020-10-23 09:45:29 +0000626 flowOutPort := flow.GetOutPort(flowItem)
627 logger.Debugw("flow-add port indications", log.Fields{
628 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
629 "uniPortName": loUniPort.name})
630 err := dh.addFlowItemToUniPort(flowItem, loUniPort)
631 //try next flow after processing error
632 if err != nil {
633 logger.Warnw("flow-add processing error: continuing on checking further flows",
634 log.Fields{"device-id": dh.deviceID, "error": err})
635 retError = err
636 continue
637 //return err
638 } else { // if last setting succeeds, overwrite possibly previously set error
639 retError = nil
640 }
641 }
642 }
643 }
644 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000645}
646
Himani Chawla6d2ae152020-09-02 13:11:20 +0530647//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000648//following are the expected device states after this activity:
649//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
650// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530651func (dh *deviceHandler) disableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000652 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000653
mpagenko900ee4b2020-10-12 11:56:34 +0000654 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000655 //note that disableDevice sequences in some 'ONU active' state may yield also
656 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000657 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000658 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000659 //disable-device shall be just a UNi/ONU-G related admin state setting
660 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000661
mpagenkofc4f56e2020-11-04 17:17:49 +0000662 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000663 // disable UNI ports/ONU
664 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
665 if dh.pLockStateFsm == nil {
666 dh.createUniLockFsm(true, UniDisableStateDone)
667 } else { //LockStateFSM already init
668 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
669 dh.runUniLockFsm(true)
670 }
671 } else {
672 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
673 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
674 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
675 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
676 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
677 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
678 }
mpagenko01e726e2020-10-23 09:45:29 +0000679 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000680
681 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000682 _ = dh.deviceReasonUpdate(drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000683 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300684 }
685}
686
Himani Chawla6d2ae152020-09-02 13:11:20 +0530687//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530688func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000689 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000690
mpagenkofc4f56e2020-11-04 17:17:49 +0000691 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
692 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
693 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
694 // for real ONU's that should have nearly no influence
695 // Note that for real ONU's there is anyway a problematic situation with following sequence:
696 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
697 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
698 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
699 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
700
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000701 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000702 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000703 if dh.pUnlockStateFsm == nil {
mpagenko900ee4b2020-10-12 11:56:34 +0000704 dh.createUniLockFsm(false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000705 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000706 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000707 dh.runUniLockFsm(false)
708 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300709}
710
Himani Chawla6d2ae152020-09-02 13:11:20 +0530711func (dh *deviceHandler) reconcileDeviceOnuInd() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000712 logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
713
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000714 pDevEntry := dh.getOnuDeviceEntry(true)
715 if pDevEntry == nil {
716 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
717 return
718 }
719 if err := pDevEntry.restoreDataFromOnuKvStore(context.TODO()); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000720 if err == fmt.Errorf("no-ONU-data-found") {
721 logger.Debugw("no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
722 } else {
723 logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
724 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000725 dh.reconciling = false
726 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000727 }
Himani Chawla4d908332020-08-31 12:30:20 +0530728 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000729 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
730 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
731 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
732 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Himani Chawla4d908332020-08-31 12:30:20 +0530733 _ = dh.createInterface(&onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000734}
735
Himani Chawla6d2ae152020-09-02 13:11:20 +0530736func (dh *deviceHandler) reconcileDeviceTechProf() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000737 logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
738
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000739 pDevEntry := dh.getOnuDeviceEntry(true)
740 if pDevEntry == nil {
741 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
742 return
743 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000744 dh.pOnuTP.lockTpProcMutex()
745 defer dh.pOnuTP.unlockTpProcMutex()
746
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000747 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
748 logger.Debugw("reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
749 log.Fields{"device-id": dh.deviceID})
750 dh.reconciling = false
751 return
752 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000753 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000754 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
755 if len(uniData.PersTpPathMap) == 0 {
756 logger.Debugw("reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
757 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
758 dh.reconciling = false
759 return
760 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800761 for tpID := range uniData.PersTpPathMap {
762 // deadline context to ensure completion of background routines waited for
763 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
764 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
765 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000766
Girish Gowdra041dcb32020-11-16 16:54:30 -0800767 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
768 var wg sync.WaitGroup
769 wg.Add(1) // for the 1 go routine to finish
770 go dh.pOnuTP.configureUniTp(dctx, uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
771 dh.waitForCompletion(cancel, &wg, "TechProfReconcile") //wait for background process to finish
772 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
773 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
774 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000775 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000776 if len(uniData.PersFlowParams) == 0 {
777 logger.Debugw("reconciling - no flows have been stored before adapter restart - terminate reconcilement",
778 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
779 dh.reconciling = false
780 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000781 }
782}
783
784func (dh *deviceHandler) reconcileDeviceFlowConfig() {
785 logger.Debugw("reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
786
787 pDevEntry := dh.getOnuDeviceEntry(true)
788 if pDevEntry == nil {
789 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000790 return
791 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000792 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
793 logger.Debugw("reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
794 log.Fields{"device-id": dh.deviceID})
795 dh.reconciling = false
796 return
797 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000798 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000799 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
800 if len(uniData.PersFlowParams) == 0 {
801 logger.Debugw("reconciling - no flows have been stored before adapter restart - terminate reconcilement",
802 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
803 dh.reconciling = false
804 return
805 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000806 var uniPort *onuUniPort
807 var exist bool
808 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
809 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
mpagenko01e726e2020-10-23 09:45:29 +0000810 logger.Errorw("onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000811 return
812 }
813 for _, flowData := range uniData.PersFlowParams {
mpagenko01e726e2020-10-23 09:45:29 +0000814 logger.Debugw("add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
815 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +0000817 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(flowData.VlanRuleParams.TpID,
818 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
819 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000820 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
821 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000822 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000823 if err := dh.createVlanFilterFsm(uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
824 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000825 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 logger.Errorw(err.Error(), log.Fields{"device-id": dh.deviceID})
827 }
828 }
829 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000830 if len(uniData.PersTpPathMap) == 0 {
831 logger.Debugw("reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
832 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
833 dh.reconciling = false
834 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000835 }
836}
837
838func (dh *deviceHandler) reconcileMetrics() {
839 logger.Debugw("reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
840
841 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000842 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000843}
844
mpagenko2418ab02020-11-12 12:58:06 +0000845func (dh *deviceHandler) deleteDevicePersistencyData() error {
846 logger.Debugw("delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000847
mpagenko2418ab02020-11-12 12:58:06 +0000848 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000849 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000850 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
851 logger.Debugw("OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
852 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000853 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000854 pDevEntry.lockOnuKVStoreMutex()
855 defer pDevEntry.unlockOnuKVStoreMutex()
856
857 // deadline context to ensure completion of background routines waited for
858 //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 +0530859 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000860 dctx, cancel := context.WithDeadline(context.Background(), deadline)
861
862 pDevEntry.resetKvProcessingErrorIndication()
863
864 var wg sync.WaitGroup
865 wg.Add(1) // for the 1 go routine to finish
866 go pDevEntry.deleteDataFromOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +0000867 dh.waitForCompletion(cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000868
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000869 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000871}
872
Himani Chawla6d2ae152020-09-02 13:11:20 +0530873func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000874 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300875 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000876 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300878 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530879 if err := dh.pOnuOmciDevice.reboot(context.TODO()); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530880 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
881 logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
882 return err
883 }
mpagenko01e726e2020-10-23 09:45:29 +0000884
885 //transfer the possibly modified logical uni port state
886 dh.disableUniPortStateUpdate()
887
Andrea Campanellabef4e542020-10-22 11:01:28 +0200888 logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000889 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
Andrea Campanellabef4e542020-10-22 11:01:28 +0200890 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300891 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000892 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
divyadesai4d299552020-08-18 07:13:49 +0000893 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300894 return err
895 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000896 if err := dh.deviceReasonUpdate(drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300897 return err
898 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000899 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000900 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
901 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
902 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
903 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300904 return nil
905}
906
Himani Chawla6d2ae152020-09-02 13:11:20 +0530907// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000908// #####################################################################################
909
910// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530911// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000912
Himani Chawla6d2ae152020-09-02 13:11:20 +0530913func (dh *deviceHandler) logStateChange(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000914 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})
915}
916
917// doStateInit provides the device update to the core
Himani Chawla6d2ae152020-09-02 13:11:20 +0530918func (dh *deviceHandler) doStateInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000919
920 logger.Debug("doStateInit-started")
921 var err error
922
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000923 // populate what we know. rest comes later after mib sync
924 dh.device.Root = false
925 dh.device.Vendor = "OpenONU"
926 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000927 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000928 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000929
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000930 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000931
932 if !dh.reconciling {
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000933 logger.Infow("DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530934 _ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000935 } else {
936 logger.Debugw("reconciling - don't notify core about DeviceUpdate",
937 log.Fields{"device-id": dh.deviceID})
938 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000939
Himani Chawla4d908332020-08-31 12:30:20 +0530940 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000941 dh.ponPortNumber = dh.device.ParentPortNo
942
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000943 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
944 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
945 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000946 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000947 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530948 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000949
950 /*
951 self._pon = PonPort.create(self, self._pon_port_number)
952 self._pon.add_peer(self.parent_id, self._pon_port_number)
953 self.logger.debug('adding-pon-port-to-agent',
954 type=self._pon.get_port().type,
955 admin_state=self._pon.get_port().admin_state,
956 oper_status=self._pon.get_port().oper_status,
957 )
958 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000959 if !dh.reconciling {
mpagenko01e726e2020-10-23 09:45:29 +0000960 logger.Debugw("adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000961 var ponPortNo uint32 = 1
962 if dh.ponPortNumber != 0 {
963 ponPortNo = dh.ponPortNumber
964 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000965
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000966 pPonPort := &voltha.Port{
967 PortNo: ponPortNo,
968 Label: fmt.Sprintf("pon-%d", ponPortNo),
969 Type: voltha.Port_PON_ONU,
970 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530971 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000972 PortNo: ponPortNo}}, // Peer port is parent's port number
973 }
974 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
975 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
976 e.Cancel(err)
977 return
978 }
979 } else {
980 logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981 }
982 logger.Debug("doStateInit-done")
983}
984
985// postInit setups the DeviceEntry for the conerned device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530986func (dh *deviceHandler) postInit(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000987
988 logger.Debug("postInit-started")
989 var err error
990 /*
991 dh.Client = oop.NewOpenoltClient(dh.clientCon)
992 dh.pTransitionMap.Handle(ctx, GrpcConnected)
993 return nil
994 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530995 if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
996 logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000997 e.Cancel(err)
998 return
999 }
1000
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001001 if dh.reconciling {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301002 go dh.reconcileDeviceOnuInd()
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001003 // reconcilement will be continued after mib download is done
1004 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001005 /*
1006 ############################################################################
1007 # Setup Alarm handler
1008 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1009 device.serial_number)
1010 ############################################################################
1011 # Setup PM configuration for this device
1012 # Pass in ONU specific options
1013 kwargs = {
1014 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1015 'heartbeat': self.heartbeat,
1016 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1017 }
1018 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1019 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1020 self.logical_device_id, device.serial_number,
1021 grouped=True, freq_override=False, **kwargs)
1022 pm_config = self._pm_metrics.make_proto()
1023 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1024 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1025 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1026
1027 # Note, ONU ID and UNI intf set in add_uni_port method
1028 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1029 ani_ports=[self._pon])
1030
1031 # Code to Run OMCI Test Action
1032 kwargs_omci_test_action = {
1033 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1034 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1035 }
1036 serial_number = device.serial_number
1037 self._test_request = OmciTestRequest(self.core_proxy,
1038 self.omci_agent, self.device_id,
1039 AniG, serial_number,
1040 self.logical_device_id,
1041 exclusive=False,
1042 **kwargs_omci_test_action)
1043
1044 self.enabled = True
1045 else:
1046 self.logger.info('onu-already-activated')
1047 */
1048 logger.Debug("postInit-done")
1049}
1050
1051// doStateConnected get the device info and update to voltha core
1052// for comparison of the original method (not that easy to uncomment): compare here:
1053// voltha-openolt-adapter/adaptercore/device_handler.go
1054// -> this one obviously initiates all communication interfaces of the device ...?
Himani Chawla6d2ae152020-09-02 13:11:20 +05301055func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001056
1057 logger.Debug("doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301058 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001059 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001060 logger.Debug("doStateConnected-done")
1061}
1062
1063// doStateUp handle the onu up indication and update to voltha core
Himani Chawla6d2ae152020-09-02 13:11:20 +05301064func (dh *deviceHandler) doStateUp(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001065
1066 logger.Debug("doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301067 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001068 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069 logger.Debug("doStateUp-done")
1070
1071 /*
1072 // Synchronous call to update device state - this method is run in its own go routine
1073 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1074 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001075 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 +00001076 return err
1077 }
1078 return nil
1079 */
1080}
1081
1082// doStateDown handle the onu down indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301083func (dh *deviceHandler) doStateDown(e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001084
1085 logger.Debug("doStateDown-started")
1086 var err error
1087
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001088 device := dh.device
1089 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090 /*TODO: needs to handle error scenarios */
Andrea Campanella6515c582020-10-05 11:25:00 +02001091 logger.Errorw("Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001092 e.Cancel(err)
1093 return
1094 }
1095
1096 cloned := proto.Clone(device).(*voltha.Device)
1097 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
1098 /*
1099 // Update the all ports state on that device to disable
1100 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001101 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001102 return er
1103 }
1104
1105 //Update the device oper state and connection status
1106 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1107 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1108 dh.device = cloned
1109
1110 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001111 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001112 return er
1113 }
1114
1115 //get the child device for the parent device
1116 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1117 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001118 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119 return err
1120 }
1121 for _, onuDevice := range onuDevices.Items {
1122
1123 // Update onu state as down in onu adapter
1124 onuInd := oop.OnuIndication{}
1125 onuInd.OperState = "down"
1126 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1127 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1128 if er != nil {
1129 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001130 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001131 //Do not return here and continue to process other ONUs
1132 }
1133 }
1134 // * Discovered ONUs entries need to be cleared , since after OLT
1135 // is up, it starts sending discovery indications again* /
1136 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001137 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001138 return nil
1139 */
Himani Chawla4d908332020-08-31 12:30:20 +05301140 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001141 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001142 logger.Debug("doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001143}
1144
Himani Chawla6d2ae152020-09-02 13:11:20 +05301145// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146// #################################################################################
1147
1148// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301149// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001150
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001151//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Himani Chawla6d2ae152020-09-02 13:11:20 +05301152func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001153 dh.lockDevice.RLock()
1154 pOnuDeviceEntry := dh.pOnuOmciDevice
1155 if aWait && pOnuDeviceEntry == nil {
1156 //keep the read sema short to allow for subsequent write
1157 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +00001158 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001159 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1160 // so it might be needed to wait here for that event with some timeout
1161 select {
1162 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +00001163 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001164 return nil
1165 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +00001166 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001167 // if written now, we can return the written value without sema
1168 return dh.pOnuOmciDevice
1169 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001170 }
mpagenko3af1f032020-06-10 08:53:41 +00001171 dh.lockDevice.RUnlock()
1172 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001173}
1174
Himani Chawla6d2ae152020-09-02 13:11:20 +05301175//setOnuDeviceEntry sets the ONU device entry within the handler
1176func (dh *deviceHandler) setOnuDeviceEntry(
1177 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001178 dh.lockDevice.Lock()
1179 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001180 dh.pOnuOmciDevice = apDeviceEntry
1181 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001182}
1183
Himani Chawla6d2ae152020-09-02 13:11:20 +05301184//addOnuDeviceEntry creates a new ONU device or returns the existing
1185func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +00001186 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001187
Himani Chawla6d2ae152020-09-02 13:11:20 +05301188 deviceEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001189 if deviceEntry == nil {
1190 /* costum_me_map in python code seems always to be None,
1191 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1192 /* also no 'clock' argument - usage open ...*/
1193 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001194 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001195 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001196 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301197 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001198 // fire deviceEntry ready event to spread to possibly waiting processing
1199 dh.deviceEntrySet <- true
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001200 logger.Debugw("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001201 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001202 logger.Debugw("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203 }
1204 // might be updated with some error handling !!!
1205 return nil
1206}
1207
Himani Chawla6d2ae152020-09-02 13:11:20 +05301208func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001209 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
1210 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1211
1212 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001213
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001214 pDevEntry := dh.getOnuDeviceEntry(true)
1215 if pDevEntry == nil {
1216 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1217 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1218 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001219 if !dh.reconciling {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001220 if err := dh.storePersistentData(); err != nil {
1221 logger.Warnw("store persistent data error - continue as there will be additional write attempts",
1222 log.Fields{"device-id": dh.deviceID, "err": err})
1223 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001224 logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1225 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001226 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1227 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1228 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1229 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1230 }
1231 } else {
1232 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
1233 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001234
1235 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
1236 logger.Debugw("reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
1237 log.Fields{"device-id": dh.deviceID})
1238 dh.reconciling = false
1239 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001240 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001241 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1242 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1243 // 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 +00001244 // 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 +00001245 // so let's just try to keep it simple ...
1246 /*
1247 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
1248 if err != nil || device == nil {
1249 //TODO: needs to handle error scenarios
1250 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1251 return errors.New("Voltha Device not found")
1252 }
1253 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001254
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001255 if err := pDevEntry.start(context.TODO()); err != nil {
1256 return err
mpagenko3af1f032020-06-10 08:53:41 +00001257 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001258
1259 _ = dh.deviceReasonUpdate(drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260
1261 /* this might be a good time for Omci Verify message? */
1262 verifyExec := make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301263 omciVerify := newOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +00001264 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001265 true, true) //exclusive and allowFailure (anyway not yet checked)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301266 omciVerify.performOmciTest(context.TODO(), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267
1268 /* give the handler some time here to wait for the OMCi verification result
1269 after Timeout start and try MibUpload FSM anyway
1270 (to prevent stopping on just not supported OMCI verification from ONU) */
1271 select {
1272 case <-time.After(2 * time.Second):
1273 logger.Warn("omci start-verification timed out (continue normal)")
1274 case testresult := <-verifyExec:
1275 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
1276 }
1277
1278 /* In py code it looks earlier (on activate ..)
1279 # Code to Run OMCI Test Action
1280 kwargs_omci_test_action = {
1281 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1282 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1283 }
1284 serial_number = device.serial_number
1285 self._test_request = OmciTestRequest(self.core_proxy,
1286 self.omci_agent, self.device_id,
1287 AniG, serial_number,
1288 self.logical_device_id,
1289 exclusive=False,
1290 **kwargs_omci_test_action)
1291 ...
1292 # Start test requests after a brief pause
1293 if not self._test_request_started:
1294 self._test_request_started = True
1295 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1296 reactor.callLater(tststart, self._test_request.start_collector)
1297
1298 */
1299 /* which is then: in omci_test_request.py : */
1300 /*
1301 def start_collector(self, callback=None):
1302 """
1303 Start the collection loop for an adapter if the frequency > 0
1304
1305 :param callback: (callable) Function to call to collect PM data
1306 """
1307 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1308 if callback is None:
1309 callback = self.perform_test_omci
1310
1311 if self.lc is None:
1312 self.lc = LoopingCall(callback)
1313
1314 if self.default_freq > 0:
1315 self.lc.start(interval=self.default_freq / 10)
1316
1317 def perform_test_omci(self):
1318 """
1319 Perform the initial test request
1320 """
1321 ani_g_entities = self._device.configuration.ani_g_entities
1322 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1323 is not None else None
1324 self._entity_id = ani_g_entities_ids[0]
1325 self.logger.info('perform-test', entity_class=self._entity_class,
1326 entity_id=self._entity_id)
1327 try:
1328 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1329 result = yield self._device.omci_cc.send(frame)
1330 if not result.fields['omci_message'].fields['success_code']:
1331 self.logger.info('Self-Test Submitted Successfully',
1332 code=result.fields[
1333 'omci_message'].fields['success_code'])
1334 else:
1335 raise TestFailure('Test Failure: {}'.format(
1336 result.fields['omci_message'].fields['success_code']))
1337 except TimeoutError as e:
1338 self.deferred.errback(failure.Failure(e))
1339
1340 except Exception as e:
1341 self.logger.exception('perform-test-Error', e=e,
1342 class_id=self._entity_class,
1343 entity_id=self._entity_id)
1344 self.deferred.errback(failure.Failure(e))
1345
1346 */
1347
1348 // PM related heartbeat??? !!!TODO....
1349 //self._heartbeat.enabled = True
1350
mpagenko1cc3cb42020-07-27 15:24:38 +00001351 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1352 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1353 * 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 +05301354 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001355 */
1356 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001357 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001358 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001359 if pMibUlFsm.Is(ulStDisabled) {
1360 if err := pMibUlFsm.Event(ulEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001361 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001362 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301363 }
1364 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1365 //Determine ONU status and start/re-start MIB Synchronization tasks
1366 //Determine if this ONU has ever synchronized
1367 if true { //TODO: insert valid check
1368 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001369 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 +00001370 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001371 }
Himani Chawla4d908332020-08-31 12:30:20 +05301372 } else {
1373 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001374 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 +00001375 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301376 }
1377 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
1378 //Examine the MIB Data Sync
1379 // callbacks to be handled:
1380 // Event(ulEvSuccess)
1381 // Event(ulEvTimeout)
1382 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001383 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001384 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001385 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001386 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001387 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001388 }
1389 } else {
divyadesai4d299552020-08-18 07:13:49 +00001390 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001391 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001392 }
1393 return nil
1394}
1395
Himani Chawla6d2ae152020-09-02 13:11:20 +05301396func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001397 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001398 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001399 if dh.deviceReason != drStoppingOpenomci {
divyadesai4d299552020-08-18 07:13:49 +00001400 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001401
mpagenko900ee4b2020-10-12 11:56:34 +00001402 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1403 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1404 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
1405 if err := dh.resetFsms(); err != nil {
1406 logger.Errorw("error-updateInterface at FSM stop",
1407 log.Fields{"device-id": dh.deviceID, "error": err})
1408 // abort: system behavior is just unstable ...
1409 return err
1410 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001411 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
mpagenko2418ab02020-11-12 12:58:06 +00001412 _ = dh.deleteDevicePersistencyData() //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001413
1414 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1415 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1416 //stop the device entry which resets the attached omciCC
Himani Chawla6d2ae152020-09-02 13:11:20 +05301417 pDevEntry := dh.getOnuDeviceEntry(false)
mpagenko3af1f032020-06-10 08:53:41 +00001418 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001419 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001420 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001421 }
mpagenko900ee4b2020-10-12 11:56:34 +00001422 _ = pDevEntry.stop(context.TODO(), false)
mpagenko3af1f032020-06-10 08:53:41 +00001423
1424 //TODO!!! remove existing traffic profiles
1425 /* from py code, if TP's exist, remove them - not yet implemented
1426 self._tp = dict()
1427 # Let TP download happen again
1428 for uni_id in self._tp_service_specific_task:
1429 self._tp_service_specific_task[uni_id].clear()
1430 for uni_id in self._tech_profile_download_done:
1431 self._tech_profile_download_done[uni_id].clear()
1432 */
1433
1434 dh.disableUniPortStateUpdate()
1435
mpagenkofc4f56e2020-11-04 17:17:49 +00001436 dh.ReadyForSpecificOmciConfig = false
1437
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001438 if err := dh.deviceReasonUpdate(drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001439 // abort: system behavior is just unstable ...
1440 return err
1441 }
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001442 logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
1443 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001444 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1445 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001446 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
mpagenko3af1f032020-06-10 08:53:41 +00001447 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001448 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001449 // abort: system behavior is just unstable ...
1450 return err
1451 }
1452 } else {
divyadesai4d299552020-08-18 07:13:49 +00001453 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001454 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001455 return nil
1456}
1457
mpagenko900ee4b2020-10-12 11:56:34 +00001458func (dh *deviceHandler) resetFsms() error {
1459 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1460 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1461 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1462 // and using the stop/reset event should never harm
1463
1464 pDevEntry := dh.getOnuDeviceEntry(false)
1465 if pDevEntry == nil {
1466 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1467 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1468 }
mpagenko900ee4b2020-10-12 11:56:34 +00001469 //the MibSync FSM might be active all the ONU-active time,
1470 // hence it must be stopped unconditionally
1471 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1472 if pMibUlFsm != nil {
1473 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1474 }
1475 //MibDownload may run
1476 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1477 if pMibDlFsm != nil {
1478 _ = pMibDlFsm.Event(dlEvReset)
1479 }
1480 //port lock/unlock FSM's may be active
1481 if dh.pUnlockStateFsm != nil {
1482 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1483 }
1484 if dh.pLockStateFsm != nil {
1485 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1486 }
1487 //techProfile related PonAniConfigFsm FSM may be active
1488 if dh.pOnuTP != nil {
1489 // should always be the case here
1490 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1491 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001492 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1493 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1494 }
mpagenko900ee4b2020-10-12 11:56:34 +00001495 }
1496 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001497 // reset the possibly existing VlanConfigFsm
1498 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1499 //VlanFilterFsm exists and was already started
1500 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1501 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001502 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001503 // no need to remove specific data
1504 pVlanFilterFsm.RequestClearPersistency(false)
1505 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001506 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1507 }
1508 }
1509 }
1510 }
1511 //TODO!!! care about PM/Alarm processing once started
1512 return nil
1513}
1514
Himani Chawla6d2ae152020-09-02 13:11:20 +05301515func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001516 logger.Debugw("MibInSync event received, adding uni ports and locking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301517
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001518 _ = dh.deviceReasonUpdate(drDiscoveryMibsyncComplete, !dh.reconciling)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301519 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001520 if pDevEntry == nil {
1521 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1522 return
1523 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001524 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Himani Chawla6d2ae152020-09-02 13:11:20 +05301525 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301526 for _, mgmtEntityID := range unigInstKeys {
1527 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
1528 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301529 dh.addUniPort(mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301530 i++
1531 }
1532 } else {
1533 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
1534 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301535 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301536 for _, mgmtEntityID := range veipInstKeys {
1537 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
1538 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301539 dh.addUniPort(mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301540 i++
1541 }
1542 } else {
1543 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
1544 }
1545 if i == 0 {
1546 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
1547 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001548 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1549 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1550 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1551 * disable/enable toggling here to allow traffic
1552 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1553 * like the py comment says:
1554 * # start by locking all the unis till mib sync and initial mib is downloaded
1555 * # this way we can capture the port down/up events when we are ready
1556 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301557
mpagenkoa40e99a2020-11-17 13:50:39 +00001558 // Init Uni Ports to Admin locked state
1559 // *** should generate UniLockStateDone event *****
1560 if dh.pLockStateFsm == nil {
1561 dh.createUniLockFsm(true, UniLockStateDone)
1562 } else { //LockStateFSM already init
1563 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
1564 dh.runUniLockFsm(true)
1565 }
1566}
1567
1568func (dh *deviceHandler) processUniLockStateDoneEvent(devEvent OnuDeviceEvent) {
1569 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301570 /* Mib download procedure -
1571 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1572 */
mpagenkoa40e99a2020-11-17 13:50:39 +00001573 pDevEntry := dh.getOnuDeviceEntry(false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001574 if pDevEntry == nil {
1575 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
1576 return
1577 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301578 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1579 if pMibDlFsm != nil {
1580 if pMibDlFsm.Is(dlStDisabled) {
1581 if err := pMibDlFsm.Event(dlEvStart); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001582 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301583 // maybe try a FSM reset and then again ... - TODO!!!
1584 } else {
1585 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1586 // maybe use more specific states here for the specific download steps ...
1587 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001588 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301589 } else {
1590 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1591 //Begin MIB data download (running autonomously)
1592 }
1593 }
1594 } else {
Andrea Campanella6515c582020-10-05 11:25:00 +02001595 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001596 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301597 // maybe try a FSM reset and then again ... - TODO!!!
1598 }
1599 /***** Mib download started */
1600 } else {
1601 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
1602 }
1603}
1604
Himani Chawla6d2ae152020-09-02 13:11:20 +05301605func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
mpagenkoa40e99a2020-11-17 13:50:39 +00001606 logger.Debugw("MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301607 //initiate DevStateUpdate
1608 if !dh.reconciling {
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001609 logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1610 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301611 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1612 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1613 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1614 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1615 } else {
1616 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
1617 }
1618 } else {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001619 pDevEntry := dh.getOnuDeviceEntry(false)
1620 if pDevEntry == nil {
1621 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1622 return
1623 }
1624 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
1625 logger.Debugw("reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked and wait for re-enabling",
1626 log.Fields{"device-id": dh.deviceID})
1627 dh.reconciling = false
1628 return
1629 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301630 logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
1631 log.Fields{"device-id": dh.deviceID})
1632 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001633 _ = dh.deviceReasonUpdate(drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001634 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301635 // *** should generate UniUnlockStateDone event *****
1636 if dh.pUnlockStateFsm == nil {
1637 dh.createUniLockFsm(false, UniUnlockStateDone)
1638 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301639 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301640 dh.runUniLockFsm(false)
1641 }
1642}
1643
Himani Chawla6d2ae152020-09-02 13:11:20 +05301644func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
mpagenko900ee4b2020-10-12 11:56:34 +00001645 dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301646
1647 if !dh.reconciling {
1648 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
1649 raisedTs := time.Now().UnixNano()
1650 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001651 pDevEntry := dh.getOnuDeviceEntry(false)
1652 if pDevEntry == nil {
1653 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1654 return
1655 }
1656 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
1657 if err := dh.storePersistentData(); err != nil {
1658 logger.Warnw("store persistent data error - continue for now as there will be additional write attempts",
1659 log.Fields{"device-id": dh.deviceID, "err": err})
1660 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301661 } else {
1662 logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
1663 log.Fields{"device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301664 go dh.reconcileDeviceTechProf()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001665 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301666 }
1667}
1668
mpagenko900ee4b2020-10-12 11:56:34 +00001669func (dh *deviceHandler) processUniDisableStateDoneEvent(devEvent OnuDeviceEvent) {
1670 logger.Debugw("DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1671 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
1672 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(),
1673 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1674 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1675 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1676 }
1677
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001678 logger.Debugw("DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001679 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001680 _ = dh.deviceReasonUpdate(drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001681
1682 //transfer the modified logical uni port state
1683 dh.disableUniPortStateUpdate()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001684
1685 pDevEntry := dh.getOnuDeviceEntry(false)
1686 if pDevEntry == nil {
1687 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1688 return
1689 }
1690 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
1691 if err := dh.storePersistentData(); err != nil {
1692 logger.Warnw("store persistent data error - continue for now as there will be additional write attempts",
1693 log.Fields{"device-id": dh.deviceID, "err": err})
1694 }
mpagenko900ee4b2020-10-12 11:56:34 +00001695}
1696
1697func (dh *deviceHandler) processUniEnableStateDoneEvent(devEvent OnuDeviceEvent) {
1698 logger.Debugw("DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
1699 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
1700 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
1701 voltha.OperStatus_ACTIVE); err != nil {
1702 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1703 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
1704 }
1705
1706 logger.Debugw("DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001707 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001708 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001709 _ = dh.deviceReasonUpdate(drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001710
1711 //transfer the modified logical uni port state
1712 dh.enableUniPortStateUpdate()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001713
1714 pDevEntry := dh.getOnuDeviceEntry(false)
1715 if pDevEntry == nil {
1716 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1717 return
1718 }
1719 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
1720 if err := dh.storePersistentData(); err != nil {
1721 logger.Warnw("store persistent data error - continue for now as there will be additional write attempts",
1722 log.Fields{"device-id": dh.deviceID, "err": err})
1723 }
mpagenko900ee4b2020-10-12 11:56:34 +00001724}
1725
Himani Chawla6d2ae152020-09-02 13:11:20 +05301726func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001727 if devEvent == OmciAniConfigDone {
1728 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
1729 // attention: the device reason update is done based on ONU-UNI-Port related activity
1730 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001731 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001732 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001733 _ = dh.deviceReasonUpdate(drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301734 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001735 if dh.reconciling {
1736 go dh.reconcileDeviceFlowConfig()
1737 }
1738 } else { // should be the OmciAniResourceRemoved block
1739 logger.Debugw("OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
1740 // attention: the device reason update is done based on ONU-UNI-Port related activity
1741 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001742 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001743 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001744 _ = dh.deviceReasonUpdate(drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001745 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001746 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301747}
1748
mpagenkofc4f56e2020-11-04 17:17:49 +00001749func (dh *deviceHandler) processOmciVlanFilterDoneEvent(aDevEvent OnuDeviceEvent) {
Himani Chawla26e555c2020-08-31 12:30:20 +05301750 logger.Debugw("OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001751 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301752 // attention: the device reason update is done based on ONU-UNI-Port related activity
1753 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301754
mpagenkofc4f56e2020-11-04 17:17:49 +00001755 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001756 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001757 // which may be the case from some previous actvity on another UNI Port of the ONU
1758 // or even some previous flow add activity on the same port
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001759 _ = dh.deviceReasonUpdate(drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001760 if dh.reconciling {
1761 go dh.reconcileMetrics()
1762 }
1763 }
1764 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001765 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001766 //not relevant for reconcile
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001767 _ = dh.deviceReasonUpdate(drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001768 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301769 }
1770}
1771
Himani Chawla6d2ae152020-09-02 13:11:20 +05301772//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
1773func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301774 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001775 case MibDatabaseSync:
1776 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301777 dh.processMibDatabaseSyncEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001778 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001779 case UniLockStateDone:
1780 {
1781 dh.processUniLockStateDoneEvent(devEvent)
1782 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001783 case MibDownloadDone:
1784 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301785 dh.processMibDownloadDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001786 }
1787 case UniUnlockStateDone:
1788 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301789 dh.processUniUnlockStateDoneEvent(devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001790 }
mpagenko900ee4b2020-10-12 11:56:34 +00001791 case UniEnableStateDone:
1792 {
1793 dh.processUniEnableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001794 }
1795 case UniDisableStateDone:
1796 {
1797 dh.processUniDisableStateDoneEvent(devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001798 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001799 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001800 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301801 dh.processOmciAniConfigDoneEvent(devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001802 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001803 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001804 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301805 dh.processOmciVlanFilterDoneEvent(devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001806 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001807 default:
1808 {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001809 logger.Debugw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001810 }
1811 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001812}
1813
Himani Chawla6d2ae152020-09-02 13:11:20 +05301814func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001815 // parameters are IntfId, OnuId, uniId
Himani Chawla6d2ae152020-09-02 13:11:20 +05301816 uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301817 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001818 if _, present := dh.uniEntityMap[uniNo]; present {
Himani Chawla4d908332020-08-31 12:30:20 +05301819 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301821 //with arguments aUniID, a_portNo, aPortType
Himani Chawla6d2ae152020-09-02 13:11:20 +05301822 pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001823 if pUniPort == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301824 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001825 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001826 //store UniPort with the System-PortNumber key
1827 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001828 if !dh.reconciling {
1829 // create announce the UniPort to the core as VOLTHA Port object
Himani Chawla6d2ae152020-09-02 13:11:20 +05301830 if err := pUniPort.createVolthaPort(dh); err == nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001831 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1832 } //error logging already within UniPort method
1833 } else {
1834 logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
1835 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836 }
1837 }
1838}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001839
mpagenko3af1f032020-06-10 08:53:41 +00001840// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301841func (dh *deviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001842 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301843 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001844 // with following remark:
1845 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1846 // # load on the core
1847
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001848 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001849
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001850 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001851 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301852 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001853 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301854 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001855 if !dh.reconciling {
1856 //maybe also use getter functions on uniPort - perhaps later ...
1857 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1858 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001859 //TODO there is no retry mechanism, return error
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001860 logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
1861 }
mpagenko3af1f032020-06-10 08:53:41 +00001862 }
1863 }
1864}
1865
1866// Disable UniPortState and update core port state accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05301867func (dh *deviceHandler) disableUniPortStateUpdate() {
mpagenko3af1f032020-06-10 08:53:41 +00001868 // compare enableUniPortStateUpdate() above
1869 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1870 for uniNo, uniPort := range dh.uniEntityMap {
1871 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301872 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
mpagenko3af1f032020-06-10 08:53:41 +00001873 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301874 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001875 //maybe also use getter functions on uniPort - perhaps later ...
1876 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001877 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001878 }
1879}
1880
1881// ONU_Active/Inactive announcement on system KAFKA bus
1882// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
Himani Chawla6d2ae152020-09-02 13:11:20 +05301883func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001884 var de voltha.DeviceEvent
1885 eventContext := make(map[string]string)
1886 //Populating event context
1887 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
Himani Chawla4d908332020-08-31 12:30:20 +05301888 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001889 if err != nil || parentDevice == nil {
1890 logger.Errorw("Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301891 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001892 }
1893 oltSerialNumber := parentDevice.SerialNumber
1894
1895 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1896 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1897 eventContext["serial-number"] = dh.device.SerialNumber
1898 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301899 eventContext["device_id"] = aDeviceID
1900 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001901 logger.Debugw("prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001902 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001903
1904 /* Populating device event body */
1905 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301906 de.ResourceId = aDeviceID
1907 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001908 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1909 de.Description = fmt.Sprintf("%s Event - %s - %s",
1910 cEventObjectType, cOnuActivatedEvent, "Raised")
1911 } else {
1912 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1913 de.Description = fmt.Sprintf("%s Event - %s - %s",
1914 cEventObjectType, cOnuActivatedEvent, "Cleared")
1915 }
1916 /* Send event to KAFKA */
1917 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1918 logger.Warnw("could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301919 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001920 }
1921 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301922 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001923}
1924
Himani Chawla4d908332020-08-31 12:30:20 +05301925// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301926func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001927 chLSFsm := make(chan Message, 2048)
1928 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301929 if aAdminState {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001930 logger.Debugw("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001931 sFsmName = "LockStateFSM"
1932 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001933 logger.Debugw("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001934 sFsmName = "UnLockStateFSM"
1935 }
mpagenko3af1f032020-06-10 08:53:41 +00001936
Himani Chawla6d2ae152020-09-02 13:11:20 +05301937 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenko3af1f032020-06-10 08:53:41 +00001938 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001939 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001940 return
1941 }
Himani Chawla6d2ae152020-09-02 13:11:20 +05301942 pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001943 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001944 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301945 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001946 dh.pLockStateFsm = pLSFsm
1947 } else {
1948 dh.pUnlockStateFsm = pLSFsm
1949 }
1950 dh.runUniLockFsm(aAdminState)
1951 } else {
divyadesai4d299552020-08-18 07:13:49 +00001952 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001953 }
1954}
1955
1956// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Himani Chawla6d2ae152020-09-02 13:11:20 +05301957func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001958 /* Uni Port lock/unlock procedure -
1959 ***** should run via 'adminDone' state and generate the argument requested event *****
1960 */
1961 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301962 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001963 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1964 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1965 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001966 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301967 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001968 }
1969 } else {
1970 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1971 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1972 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001973 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301974 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001975 }
1976 }
1977 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001978 if pLSStatemachine.Is(uniStDisabled) {
1979 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001980 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1981 // maybe try a FSM reset and then again ... - TODO!!!
1982 } else {
1983 /***** LockStateFSM started */
1984 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001985 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001986 }
1987 } else {
1988 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001989 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001990 // maybe try a FSM reset and then again ... - TODO!!!
1991 }
1992 } else {
divyadesai4d299552020-08-18 07:13:49 +00001993 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001994 // maybe try a FSM reset and then again ... - TODO!!!
1995 }
1996}
1997
Himani Chawla6d2ae152020-09-02 13:11:20 +05301998//setBackend provides a DB backend for the specified path on the existing KV client
1999func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002000 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
2001 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002002 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002003 kvbackend := &db.Backend{
2004 Client: dh.pOpenOnuAc.kvClient,
2005 StoreType: dh.pOpenOnuAc.KVStoreType,
2006 /* address config update acc. to [VOL-2736] */
2007 Address: addr,
2008 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2009 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002010
mpagenkoaf801632020-07-03 10:00:42 +00002011 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002012}
Himani Chawla6d2ae152020-09-02 13:11:20 +05302013func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302014 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002015
mpagenkodff5dda2020-08-28 11:52:01 +00002016 for _, field := range flow.GetOfbFields(apFlowItem) {
2017 switch field.Type {
2018 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2019 {
mpagenko01e726e2020-10-23 09:45:29 +00002020 logger.Debugw("flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002021 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2022 }
mpagenko01e726e2020-10-23 09:45:29 +00002023 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002024 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2025 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302026 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002027 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302028 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2029 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002030 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2031 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002032 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2033 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302034 return
mpagenkodff5dda2020-08-28 11:52:01 +00002035 }
2036 }
mpagenko01e726e2020-10-23 09:45:29 +00002037 */
mpagenkodff5dda2020-08-28 11:52:01 +00002038 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2039 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302040 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002041 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302042 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002043 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302044 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002045 }
mpagenko01e726e2020-10-23 09:45:29 +00002046 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302047 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002048 }
2049 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2050 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302051 *loAddPcp = uint8(field.GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002052 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002053 "PCP": loAddPcp})
2054 }
2055 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2056 {
mpagenko01e726e2020-10-23 09:45:29 +00002057 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002058 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2059 }
2060 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2061 {
mpagenko01e726e2020-10-23 09:45:29 +00002062 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002063 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2064 }
2065 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2066 {
mpagenko01e726e2020-10-23 09:45:29 +00002067 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002068 "IPv4-DST": field.GetIpv4Dst()})
2069 }
2070 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2071 {
mpagenko01e726e2020-10-23 09:45:29 +00002072 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002073 "IPv4-SRC": field.GetIpv4Src()})
2074 }
2075 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2076 {
mpagenko01e726e2020-10-23 09:45:29 +00002077 logger.Debugw("flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002078 "Metadata": field.GetTableMetadata()})
2079 }
2080 /*
2081 default:
2082 {
2083 //all other entires ignored
2084 }
2085 */
2086 }
2087 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302088}
mpagenkodff5dda2020-08-28 11:52:01 +00002089
Himani Chawla6d2ae152020-09-02 13:11:20 +05302090func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002091 for _, action := range flow.GetActions(apFlowItem) {
2092 switch action.Type {
2093 /* not used:
2094 case of.OfpActionType_OFPAT_OUTPUT:
2095 {
mpagenko01e726e2020-10-23 09:45:29 +00002096 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002097 "Output": action.GetOutput()})
2098 }
2099 */
2100 case of.OfpActionType_OFPAT_PUSH_VLAN:
2101 {
mpagenko01e726e2020-10-23 09:45:29 +00002102 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002103 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2104 }
2105 case of.OfpActionType_OFPAT_SET_FIELD:
2106 {
2107 pActionSetField := action.GetSetField()
2108 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
mpagenko01e726e2020-10-23 09:45:29 +00002109 logger.Warnw("flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002110 "OxcmClass": pActionSetField.Field.OxmClass})
2111 }
2112 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302113 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
mpagenko01e726e2020-10-23 09:45:29 +00002114 logger.Debugw("flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302115 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002116 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302117 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
mpagenko01e726e2020-10-23 09:45:29 +00002118 logger.Debugw("flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302119 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002120 } else {
mpagenko01e726e2020-10-23 09:45:29 +00002121 logger.Warnw("flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002122 "Type": pActionSetField.Field.GetOfbField().Type})
2123 }
2124 }
2125 /*
2126 default:
2127 {
2128 //all other entires ignored
2129 }
2130 */
2131 }
2132 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302133}
2134
2135//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Himani Chawla6d2ae152020-09-02 13:11:20 +05302136func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302137 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2138 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2139 var loAddPcp, loSetPcp uint8
2140 var loIPProto uint32
2141 /* the TechProfileId is part of the flow Metadata - compare also comment within
2142 * OLT-Adapter:openolt_flowmgr.go
2143 * Metadata 8 bytes:
2144 * Most Significant 2 Bytes = Inner VLAN
2145 * Next 2 Bytes = Tech Profile ID(TPID)
2146 * Least Significant 4 Bytes = Port ID
2147 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2148 * subscriber related flows.
2149 */
2150
2151 metadata := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
2152 if metadata == 0 {
mpagenko01e726e2020-10-23 09:45:29 +00002153 logger.Debugw("flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302154 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002155 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 }
2157 loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002158 loCookie := apFlowItem.GetCookie()
2159 loCookieSlice := []uint64{loCookie}
2160 logger.Debugw("flow-add base indications", log.Fields{"device-id": dh.deviceID,
2161 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302162
2163 dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002164 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302165 if loIPProto == 2 {
2166 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2167 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002168 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2169 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302170 return nil
2171 }
mpagenko01e726e2020-10-23 09:45:29 +00002172 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302173 dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002174
2175 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002176 logger.Errorw("flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002177 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2178 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2179 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2180 //TODO!!: Use DeviceId within the error response to rwCore
2181 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002182 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002183 }
2184 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
mpagenko01e726e2020-10-23 09:45:29 +00002185 logger.Debugw("flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002186 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2187 } else {
2188 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2189 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2190 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302191 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002192 }
mpagenko01e726e2020-10-23 09:45:29 +00002193 logger.Debugw("flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002194 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302195 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko01e726e2020-10-23 09:45:29 +00002196 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(loTpID, loCookieSlice,
2197 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002198 }
mpagenko01e726e2020-10-23 09:45:29 +00002199 return dh.createVlanFilterFsm(apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002200 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002201}
2202
2203//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
2204func (dh *deviceHandler) removeFlowItemFromUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
2205 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2206 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2207 //no extra check is done on the rule parameters
2208 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2209 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2210 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2211 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002212 // - some possible 'delete-all' sequence would have to be implemented separately (where the cookies are don't care anyway)
mpagenko01e726e2020-10-23 09:45:29 +00002213 loCookie := apFlowItem.GetCookie()
2214 logger.Debugw("flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
2215
2216 /* TT related temporary workaround - should not be needed anymore
2217 for _, field := range flow.GetOfbFields(apFlowItem) {
2218 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2219 loIPProto := field.GetIpProto()
2220 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2221 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2222 if loIPProto == 2 {
2223 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2224 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2225 log.Fields{"device-id": dh.deviceID})
2226 return nil
2227 }
2228 }
2229 } //for all OfbFields
2230 */
2231
2232 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
2233 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(loCookie)
2234 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002235 logger.Debugw("flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002236 log.Fields{"device-id": dh.deviceID})
2237 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002238 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
2239 go dh.deviceProcStatusUpdate(OmciVlanFilterRemDone)
2240
mpagenko01e726e2020-10-23 09:45:29 +00002241 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002242}
2243
Himani Chawla26e555c2020-08-31 12:30:20 +05302244// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko01e726e2020-10-23 09:45:29 +00002245func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
2246 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002247 chVlanFilterFsm := make(chan Message, 2048)
2248
Himani Chawla6d2ae152020-09-02 13:11:20 +05302249 pDevEntry := dh.getOnuDeviceEntry(true)
mpagenkodff5dda2020-08-28 11:52:01 +00002250 if pDevEntry == nil {
2251 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302252 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002253 }
2254
2255 pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002256 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2257 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002258 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302259 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002260 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2261 if pVlanFilterStatemachine != nil {
2262 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2263 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
2264 logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302265 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002266 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302267 /***** UniVlanConfigFsm started */
2268 logger.Debugw("UniVlanConfigFsm started", log.Fields{
2269 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2270 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002271 } else {
2272 logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
2273 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302274 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002275 }
2276 } else {
2277 logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
2278 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302279 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002280 }
2281 } else {
2282 logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
2283 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302284 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002285 }
2286 return nil
2287}
2288
mpagenkofc4f56e2020-11-04 17:17:49 +00002289//VerifyVlanConfigRequest checks on existence of a given uniPort
2290// and starts verification of flow config based on that
2291func (dh *deviceHandler) VerifyVlanConfigRequest(aUniID uint8) {
2292 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2293 var pCurrentUniPort *onuUniPort
2294 for _, uniPort := range dh.uniEntityMap {
2295 // only if this port is validated for operState transfer
2296 if uniPort.uniID == uint8(aUniID) {
2297 pCurrentUniPort = uniPort
2298 break //found - end search loop
2299 }
2300 }
2301 if pCurrentUniPort == nil {
2302 logger.Debugw("VerifyVlanConfig aborted: requested uniID not found in PortDB",
2303 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2304 return
2305 }
2306 dh.verifyUniVlanConfigRequest(pCurrentUniPort)
2307}
2308
mpagenkodff5dda2020-08-28 11:52:01 +00002309//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Himani Chawla6d2ae152020-09-02 13:11:20 +05302310func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002311 //TODO!! verify and start pending flow configuration
2312 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2313 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302314 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002315 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2316 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2317 if pVlanFilterStatemachine != nil {
2318 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2319 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2320 logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
2321 } else {
2322 /***** UniVlanConfigFsm continued */
2323 logger.Debugw("UniVlanConfigFsm continued", log.Fields{
2324 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2325 "UniPort": apUniPort.portNo})
2326 }
2327 } else {
2328 logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
2329 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2330 }
2331 } else {
2332 logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
2333 "device-id": dh.deviceID})
2334 }
2335
2336 } // else: nothing to do
2337}
2338
2339//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2340// 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 +05302341func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002342 logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
2343 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2344 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002346}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002347
2348//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2349//available for potential reconcilement
2350
2351func (dh *deviceHandler) storePersUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
2352
2353 if dh.reconciling {
2354 logger.Debugw("reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
2355 return nil
2356 }
mpagenko2418ab02020-11-12 12:58:06 +00002357 logger.Debugw("Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002358
2359 pDevEntry := dh.getOnuDeviceEntry(true)
2360 if pDevEntry == nil {
2361 logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2362 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2363 }
2364 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2365
2366 pDevEntry.lockOnuKVStoreMutex()
2367 defer pDevEntry.unlockOnuKVStoreMutex()
2368
2369 // deadline context to ensure completion of background routines waited for
2370 //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 +05302371 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002372 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2373
2374 pDevEntry.resetKvProcessingErrorIndication()
2375 var wg sync.WaitGroup
2376 wg.Add(1) // for the 1 go routine to finish
2377
2378 go pDevEntry.updateOnuKvStore(dctx, &wg)
mpagenko01e726e2020-10-23 09:45:29 +00002379 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002380
2381 return pDevEntry.getKvProcessingErrorIndication()
2382}
2383
mpagenko01e726e2020-10-23 09:45:29 +00002384func (dh *deviceHandler) waitForCompletion(cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002385 defer cancel() //ensure termination of context (may be pro forma)
2386 wg.Wait()
mpagenko01e726e2020-10-23 09:45:29 +00002387 logger.Debugw("WaitGroup processing completed", log.Fields{
2388 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002389}
2390
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002391func (dh *deviceHandler) deviceReasonUpdate(deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002392
2393 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002394 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002395 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002396 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2397 logger.Errorf("DeviceReasonUpdate error: %s",
2398 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002399 return err
2400 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002401 logger.Infof("DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002402 return nil
2403 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002404 logger.Infof("Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
2405 return nil
2406}
2407
2408func (dh *deviceHandler) storePersistentData() error {
2409 pDevEntry := dh.getOnuDeviceEntry(true)
2410 if pDevEntry == nil {
2411 logger.Warnw("No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
2412 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2413 }
2414 pDevEntry.lockOnuKVStoreMutex()
2415 defer pDevEntry.unlockOnuKVStoreMutex()
2416
2417 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2418 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2419
2420 pDevEntry.resetKvProcessingErrorIndication()
2421 var wg sync.WaitGroup
2422 wg.Add(1) // for the 1 go routine to finish
2423
2424 go pDevEntry.updateOnuKvStore(dctx, &wg)
2425 dh.waitForCompletion(cancel, &wg, "UpdateKvStore") //wait for background process to finish
2426
2427 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
2428 logger.Warnw("KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
2429 return err
2430 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002431 return nil
2432}
2433
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002434func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2435 var errStr string = ""
2436 for _, err := range errS {
2437 if err != nil {
2438 errStr = errStr + err.Error() + " "
2439 }
2440 }
2441 if errStr != "" {
2442 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2443 }
2444 return nil
2445}