blob: a4da5355de4e1d80ee77a8969a6a46b109a47248 [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"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
34 "github.com/opencord/voltha-lib-go/v4/pkg/db"
35 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
36 "github.com/opencord/voltha-lib-go/v4/pkg/log"
37 vc "github.com/opencord/voltha-protos/v4/go/common"
38 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
39 "github.com/opencord/voltha-protos/v4/go/openflow_13"
40 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 oop "github.com/opencord/voltha-protos/v4/go/openolt"
43 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000044)
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
mpagenkofc4f56e2020-11-04 17:17:49 +0000165 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000166 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000167 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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000173func newDeviceHandler(ctx context.Context, cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530174 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))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000190 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530191 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000192 dh.lockVlanConfig = sync.Mutex{}
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{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000208 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
209 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
210 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
211 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
212 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
213 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
214 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
215 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, 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) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000224 logger.Debugw(ctx, "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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000226 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227}
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) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000242 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243
dbainbri4d3a0dc2020-12-02 00:33:42 +0000244 logger.Debugw(ctx, "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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000247 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000249 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000251 logger.Debugw(ctx, "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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000256func (dh *deviceHandler) processInterAdapterOMCIReqMessage(ctx context.Context, 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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000260 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530261 "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]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000267 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530268 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
269 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000270 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530271 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000272 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000273 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000274 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000275 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530276 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Errorw(ctx, "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(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000282 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530283 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000284
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000286
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000288 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000290 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
291 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530292 if dh.pOnuTP == nil {
293 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530295 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000296 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530297 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000298 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000300 "device-state": deviceReasonMap[dh.deviceReason]})
301 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530302 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000303 //previous state test here was just this one, now extended for more states to reject the SetRequest:
304 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
305 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530306
307 msgBody := msg.GetBody()
308 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
309 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530311 "device-id": dh.deviceID, "error": err})
312 return err
313 }
314
315 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000316 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
317 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530318 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000319 defer dh.pOnuTP.unlockTpProcMutex()
320 pDevEntry.lockOnuKVStoreMutex()
321 defer pDevEntry.unlockOnuKVStoreMutex()
322
323 if techProfMsg.UniId > 255 {
324 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
325 techProfMsg.UniId, dh.deviceID))
326 }
327 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800328 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
329 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800331 return err
332 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000333
dbainbri4d3a0dc2020-12-02 00:33:42 +0000334 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530335 // if there has been some change for some uni TechProfilePath
336 //in order to allow concurrent calls to other dh instances we do not wait for execution here
337 //but doing so we can not indicate problems to the caller (who does what with that then?)
338 //by now we just assume straightforward successful execution
339 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
340 // possible problems to the caller later autonomously
341
342 // deadline context to ensure completion of background routines waited for
343 //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 +0530344 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 dctx, cancel := context.WithDeadline(context.Background(), deadline)
346
Girish Gowdra041dcb32020-11-16 16:54:30 -0800347 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000348 pDevEntry.resetKvProcessingErrorIndication()
349
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 var wg sync.WaitGroup
351 wg.Add(2) // for the 2 go routines to finish
352 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
354 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
355 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000356
Girish Gowdra041dcb32020-11-16 16:54:30 -0800357 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000359 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 return nil
361}
362
Himani Chawla6d2ae152020-09-02 13:11:20 +0530363func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 msg *ic.InterAdapterMessage) error {
366
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000368
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
373 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 if dh.pOnuTP == nil {
375 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000376 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 }
380
381 msgBody := msg.GetBody()
382 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
383 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530385 "device-id": dh.deviceID, "error": err})
386 return err
387 }
388
389 //compare TECH_PROFILE_DOWNLOAD_REQUEST
390 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000391 defer dh.pOnuTP.unlockTpProcMutex()
392 pDevEntry.lockOnuKVStoreMutex()
393 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530394
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395 if delGemPortMsg.UniId > 255 {
396 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
397 delGemPortMsg.UniId, dh.deviceID))
398 }
399 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800400 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
401 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800403 return err
404 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530405
mpagenkofc4f56e2020-11-04 17:17:49 +0000406 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000407
mpagenkofc4f56e2020-11-04 17:17:49 +0000408 // deadline context to ensure completion of background routines waited for
409 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
410 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411
Girish Gowdra041dcb32020-11-16 16:54:30 -0800412 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
mpagenkofc4f56e2020-11-04 17:17:49 +0000414 var wg sync.WaitGroup
415 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000417 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000419
Girish Gowdra041dcb32020-11-16 16:54:30 -0800420 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530421}
422
Himani Chawla6d2ae152020-09-02 13:11:20 +0530423func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000426
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000428
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000430 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
433 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530434 if dh.pOnuTP == nil {
435 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000436 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530437 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000438 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530439 }
440
441 msgBody := msg.GetBody()
442 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
443 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530445 "device-id": dh.deviceID, "error": err})
446 return err
447 }
448
449 //compare TECH_PROFILE_DOWNLOAD_REQUEST
450 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000451 defer dh.pOnuTP.unlockTpProcMutex()
452 pDevEntry.lockOnuKVStoreMutex()
453 defer pDevEntry.unlockOnuKVStoreMutex()
454
455 if delTcontMsg.UniId > 255 {
456 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
457 delTcontMsg.UniId, dh.deviceID))
458 }
459 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800460 tpPath := delTcontMsg.TpPath
461 tpID, err := GetTpIDFromTpPath(tpPath)
462 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800464 return err
465 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466
dbainbri4d3a0dc2020-12-02 00:33:42 +0000467 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530468 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530469 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 dctx, cancel := context.WithDeadline(context.Background(), deadline)
471
Girish Gowdra041dcb32020-11-16 16:54:30 -0800472 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000473 pDevEntry.resetKvProcessingErrorIndication()
474
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 var wg sync.WaitGroup
476 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530478 cResourceTcont, delTcontMsg.AllocId, &wg)
479 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
481 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482
Girish Gowdra041dcb32020-11-16 16:54:30 -0800483 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 return nil
486}
487
Himani Chawla6d2ae152020-09-02 13:11:20 +0530488//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000489// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
490// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000492 msgID := msg.Header.Id
493 msgType := msg.Header.Type
494 fromTopic := msg.Header.FromTopic
495 toTopic := msg.Header.ToTopic
496 toDeviceID := msg.Header.ToDeviceId
497 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000499 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
500
501 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000502 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000503 case ic.InterAdapterMessageType_OMCI_REQUEST:
504 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000505 return dh.processInterAdapterOMCIReqMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000506 }
mpagenkoaf801632020-07-03 10:00:42 +0000507 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
508 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000510 }
511 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
512 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000514
mpagenkoaf801632020-07-03 10:00:42 +0000515 }
516 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
517 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000518 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000519 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000520 default:
521 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000522 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 "msgType": msg.Header.Type, "device-id": dh.deviceID})
524 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000525 }
526 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000527}
528
mpagenkodff5dda2020-08-28 11:52:01 +0000529//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
531 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000532 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000534
mpagenko01e726e2020-10-23 09:45:29 +0000535 var retError error = nil
536 //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 +0000537 if apOfFlowChanges.ToRemove != nil {
538 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000539 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000541 "device-id": dh.deviceID})
542 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000543 continue
544 }
545 flowInPort := flow.GetInPort(flowItem)
546 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000548 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
549 continue
550 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000551 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000552 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000554 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000555 continue
556 } else {
557 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530558 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000559 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
560 loUniPort = uniPort
561 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000562 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000563 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
564 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
565 flowInPort, dh.deviceID)
566 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000567 }
568 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000570 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000571 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000573 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000574 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000576 log.Fields{"device-id": dh.deviceID, "error": err})
577 retError = err
578 continue
579 //return err
580 } else { // if last setting succeeds, overwrite possibly previously set error
581 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000582 }
583 }
584 }
585 }
mpagenko01e726e2020-10-23 09:45:29 +0000586 if apOfFlowChanges.ToAdd != nil {
587 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
588 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000590 "device-id": dh.deviceID})
591 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
592 continue
593 }
594 flowInPort := flow.GetInPort(flowItem)
595 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000597 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
598 continue
599 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
600 } else if flowInPort == dh.ponPortNumber {
601 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000602 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000603 "device-id": dh.deviceID, "inPort": flowInPort})
604 continue
605 } else {
606 // this is the relevant upstream flow
607 var loUniPort *onuUniPort
608 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
609 loUniPort = uniPort
610 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000612 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
613 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
614 flowInPort, dh.deviceID)
615 continue
616 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
617 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000618 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
619 // if not, we just throw some error here to have an indication about that, if we really need to support that
620 // then we would need to create some means to activate the internal stored flows
621 // after the device gets active automatically (and still with its dependency to the TechProfile)
622 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
623 // also abort for the other still possible flows here
624 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000626 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000627 return fmt.Errorf("improper device state on device %s", dh.deviceID)
628 }
629
mpagenko01e726e2020-10-23 09:45:29 +0000630 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000632 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
633 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000635 //try next flow after processing error
636 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000638 log.Fields{"device-id": dh.deviceID, "error": err})
639 retError = err
640 continue
641 //return err
642 } else { // if last setting succeeds, overwrite possibly previously set error
643 retError = nil
644 }
645 }
646 }
647 }
648 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000649}
650
Himani Chawla6d2ae152020-09-02 13:11:20 +0530651//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000652//following are the expected device states after this activity:
653//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
654// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
656 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000657
mpagenko900ee4b2020-10-12 11:56:34 +0000658 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000659 //note that disableDevice sequences in some 'ONU active' state may yield also
660 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000661 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000662 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000663 //disable-device shall be just a UNi/ONU-G related admin state setting
664 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000665
mpagenkofc4f56e2020-11-04 17:17:49 +0000666 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000667 // disable UNI ports/ONU
668 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
669 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000671 } else { //LockStateFSM already init
672 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000674 }
675 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000677 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000679 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
680 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000682 }
mpagenko01e726e2020-10-23 09:45:29 +0000683 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000684
685 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000687 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300688 }
689}
690
Himani Chawla6d2ae152020-09-02 13:11:20 +0530691//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
693 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000694
mpagenkofc4f56e2020-11-04 17:17:49 +0000695 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
696 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
697 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
698 // for real ONU's that should have nearly no influence
699 // Note that for real ONU's there is anyway a problematic situation with following sequence:
700 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
701 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
702 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
703 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
704
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000705 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000706 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000707 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000709 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000710 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000712 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300713}
714
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
716 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000717
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000719 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000721 return
722 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000724 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000725 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000726 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000728 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000729 dh.reconciling = false
730 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000731 }
Himani Chawla4d908332020-08-31 12:30:20 +0530732 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000733 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
734 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
735 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
736 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000738}
739
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
741 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000742
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000744 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000746 return
747 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000748 dh.pOnuTP.lockTpProcMutex()
749 defer dh.pOnuTP.unlockTpProcMutex()
750
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000751 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000753 log.Fields{"device-id": dh.deviceID})
754 dh.reconciling = false
755 return
756 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000757 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000758 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
759 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000761 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
762 dh.reconciling = false
763 return
764 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800765 for tpID := range uniData.PersTpPathMap {
766 // deadline context to ensure completion of background routines waited for
767 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
768 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000770
Girish Gowdra041dcb32020-11-16 16:54:30 -0800771 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
772 var wg sync.WaitGroup
773 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
775 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800776 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800778 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000779 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000780 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000782 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
783 dh.reconciling = false
784 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000785 }
786}
787
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
789 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000794 return
795 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000796 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000798 log.Fields{"device-id": dh.deviceID})
799 dh.reconciling = false
800 return
801 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000802 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000803 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
804 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000806 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
807 dh.reconciling = false
808 return
809 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000810 var uniPort *onuUniPort
811 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000813 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000815 return
816 }
817 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000819 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000820 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000822 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
823 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000826 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000828 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000829 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 }
832 }
833 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000834 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000836 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
837 dh.reconciling = false
838 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000839 }
840}
841
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
843 logger.Debugw(ctx, "reconciling - trigger metrics - to be implemented in scope of VOL-3324!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000844
845 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000846 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000847}
848
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
850 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000851
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000853 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000854 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000856 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000857 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000858 pDevEntry.lockOnuKVStoreMutex()
859 defer pDevEntry.unlockOnuKVStoreMutex()
860
861 // deadline context to ensure completion of background routines waited for
862 //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 +0530863 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000865
866 pDevEntry.resetKvProcessingErrorIndication()
867
868 var wg sync.WaitGroup
869 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
871 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000873 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000875}
876
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
878 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300879 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000881 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300882 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530884 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530886 return err
887 }
mpagenko01e726e2020-10-23 09:45:29 +0000888
889 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000891
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000893 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300895 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000896 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000897 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300898 return err
899 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300901 return err
902 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000903 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000904 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
905 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
906 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
907 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300908 return nil
909}
910
Himani Chawla6d2ae152020-09-02 13:11:20 +0530911// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000912// #####################################################################################
913
914// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530915// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000916
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
918 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000919}
920
921// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000922func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000923
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000925 var err error
926
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000927 // populate what we know. rest comes later after mib sync
928 dh.device.Root = false
929 dh.device.Vendor = "OpenONU"
930 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000931 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000932 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000933
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000934 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000935
936 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
938 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000939 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000941 log.Fields{"device-id": dh.deviceID})
942 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000943
Himani Chawla4d908332020-08-31 12:30:20 +0530944 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000945 dh.ponPortNumber = dh.device.ParentPortNo
946
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000947 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
948 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
949 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000951 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +0530952 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000953
954 /*
955 self._pon = PonPort.create(self, self._pon_port_number)
956 self._pon.add_peer(self.parent_id, self._pon_port_number)
957 self.logger.debug('adding-pon-port-to-agent',
958 type=self._pon.get_port().type,
959 admin_state=self._pon.get_port().admin_state,
960 oper_status=self._pon.get_port().oper_status,
961 )
962 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000963 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000965 var ponPortNo uint32 = 1
966 if dh.ponPortNumber != 0 {
967 ponPortNo = dh.ponPortNumber
968 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000969
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000970 pPonPort := &voltha.Port{
971 PortNo: ponPortNo,
972 Label: fmt.Sprintf("pon-%d", ponPortNo),
973 Type: voltha.Port_PON_ONU,
974 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +0530975 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000976 PortNo: ponPortNo}}, // Peer port is parent's port number
977 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
979 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000980 e.Cancel(err)
981 return
982 }
983 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000984 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000985 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000987}
988
989// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000990func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000991
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000993 var err error
994 /*
995 dh.Client = oop.NewOpenoltClient(dh.clientCon)
996 dh.pTransitionMap.Handle(ctx, GrpcConnected)
997 return nil
998 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1000 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001001 e.Cancel(err)
1002 return
1003 }
1004
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001005 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001007 // reconcilement will be continued after mib download is done
1008 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001009 /*
1010 ############################################################################
1011 # Setup Alarm handler
1012 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1013 device.serial_number)
1014 ############################################################################
1015 # Setup PM configuration for this device
1016 # Pass in ONU specific options
1017 kwargs = {
1018 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1019 'heartbeat': self.heartbeat,
1020 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1021 }
1022 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1023 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1024 self.logical_device_id, device.serial_number,
1025 grouped=True, freq_override=False, **kwargs)
1026 pm_config = self._pm_metrics.make_proto()
1027 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1028 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1029 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1030
1031 # Note, ONU ID and UNI intf set in add_uni_port method
1032 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1033 ani_ports=[self._pon])
1034
1035 # Code to Run OMCI Test Action
1036 kwargs_omci_test_action = {
1037 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1038 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1039 }
1040 serial_number = device.serial_number
1041 self._test_request = OmciTestRequest(self.core_proxy,
1042 self.omci_agent, self.device_id,
1043 AniG, serial_number,
1044 self.logical_device_id,
1045 exclusive=False,
1046 **kwargs_omci_test_action)
1047
1048 self.enabled = True
1049 else:
1050 self.logger.info('onu-already-activated')
1051 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001052 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001053}
1054
1055// doStateConnected get the device info and update to voltha core
1056// for comparison of the original method (not that easy to uncomment): compare here:
1057// voltha-openolt-adapter/adaptercore/device_handler.go
1058// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001059func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001060
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301062 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001063 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001065}
1066
1067// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001068func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001069
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301071 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001072 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074
1075 /*
1076 // Synchronous call to update device state - this method is run in its own go routine
1077 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1078 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001079 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 +00001080 return err
1081 }
1082 return nil
1083 */
1084}
1085
1086// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001087func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001088
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001090 var err error
1091
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001092 device := dh.device
1093 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001094 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001095 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001096 e.Cancel(err)
1097 return
1098 }
1099
1100 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001102 /*
1103 // Update the all ports state on that device to disable
1104 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001105 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001106 return er
1107 }
1108
1109 //Update the device oper state and connection status
1110 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1111 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1112 dh.device = cloned
1113
1114 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001115 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116 return er
1117 }
1118
1119 //get the child device for the parent device
1120 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1121 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001122 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001123 return err
1124 }
1125 for _, onuDevice := range onuDevices.Items {
1126
1127 // Update onu state as down in onu adapter
1128 onuInd := oop.OnuIndication{}
1129 onuInd.OperState = "down"
1130 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1131 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1132 if er != nil {
1133 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001134 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001135 //Do not return here and continue to process other ONUs
1136 }
1137 }
1138 // * Discovered ONUs entries need to be cleared , since after OLT
1139 // is up, it starts sending discovery indications again* /
1140 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001141 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001142 return nil
1143 */
Himani Chawla4d908332020-08-31 12:30:20 +05301144 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001145 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147}
1148
Himani Chawla6d2ae152020-09-02 13:11:20 +05301149// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001150// #################################################################################
1151
1152// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301153// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001154
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001155//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001157 dh.lockDevice.RLock()
1158 pOnuDeviceEntry := dh.pOnuOmciDevice
1159 if aWait && pOnuDeviceEntry == nil {
1160 //keep the read sema short to allow for subsequent write
1161 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001163 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1164 // so it might be needed to wait here for that event with some timeout
1165 select {
1166 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001167 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001168 return nil
1169 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001170 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001171 // if written now, we can return the written value without sema
1172 return dh.pOnuOmciDevice
1173 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001174 }
mpagenko3af1f032020-06-10 08:53:41 +00001175 dh.lockDevice.RUnlock()
1176 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001177}
1178
Himani Chawla6d2ae152020-09-02 13:11:20 +05301179//setOnuDeviceEntry sets the ONU device entry within the handler
1180func (dh *deviceHandler) setOnuDeviceEntry(
1181 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001182 dh.lockDevice.Lock()
1183 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001184 dh.pOnuOmciDevice = apDeviceEntry
1185 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001186}
1187
Himani Chawla6d2ae152020-09-02 13:11:20 +05301188//addOnuDeviceEntry creates a new ONU device or returns the existing
1189func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001190 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001191
dbainbri4d3a0dc2020-12-02 00:33:42 +00001192 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001193 if deviceEntry == nil {
1194 /* costum_me_map in python code seems always to be None,
1195 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1196 /* also no 'clock' argument - usage open ...*/
1197 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001198 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001199 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001200 //error treatment possible //TODO!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +05301201 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +00001202 // fire deviceEntry ready event to spread to possibly waiting processing
1203 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001204 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001205 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001207 }
1208 // might be updated with some error handling !!!
1209 return nil
1210}
1211
dbainbri4d3a0dc2020-12-02 00:33:42 +00001212func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1213 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001214 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1215
1216 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001217
dbainbri4d3a0dc2020-12-02 00:33:42 +00001218 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001219 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001221 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1222 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001223 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001224 if err := dh.storePersistentData(ctx); err != nil {
1225 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001226 log.Fields{"device-id": dh.deviceID, "err": err})
1227 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001229 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001231 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1232 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001233 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001234 }
1235 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001237 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001238
1239 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001240 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001241 log.Fields{"device-id": dh.deviceID})
1242 dh.reconciling = false
1243 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001244 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001245 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1246 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1247 // 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 +00001248 // 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 +00001249 // so let's just try to keep it simple ...
1250 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001252 if err != nil || device == nil {
1253 //TODO: needs to handle error scenarios
1254 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1255 return errors.New("Voltha Device not found")
1256 }
1257 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001258
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001260 return err
mpagenko3af1f032020-06-10 08:53:41 +00001261 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001262
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001264
1265 /* this might be a good time for Omci Verify message? */
1266 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001268 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001269 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001270 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001271
1272 /* give the handler some time here to wait for the OMCi verification result
1273 after Timeout start and try MibUpload FSM anyway
1274 (to prevent stopping on just not supported OMCI verification from ONU) */
1275 select {
1276 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001277 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001278 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001280 }
1281
1282 /* In py code it looks earlier (on activate ..)
1283 # Code to Run OMCI Test Action
1284 kwargs_omci_test_action = {
1285 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1286 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1287 }
1288 serial_number = device.serial_number
1289 self._test_request = OmciTestRequest(self.core_proxy,
1290 self.omci_agent, self.device_id,
1291 AniG, serial_number,
1292 self.logical_device_id,
1293 exclusive=False,
1294 **kwargs_omci_test_action)
1295 ...
1296 # Start test requests after a brief pause
1297 if not self._test_request_started:
1298 self._test_request_started = True
1299 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1300 reactor.callLater(tststart, self._test_request.start_collector)
1301
1302 */
1303 /* which is then: in omci_test_request.py : */
1304 /*
1305 def start_collector(self, callback=None):
1306 """
1307 Start the collection loop for an adapter if the frequency > 0
1308
1309 :param callback: (callable) Function to call to collect PM data
1310 """
1311 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1312 if callback is None:
1313 callback = self.perform_test_omci
1314
1315 if self.lc is None:
1316 self.lc = LoopingCall(callback)
1317
1318 if self.default_freq > 0:
1319 self.lc.start(interval=self.default_freq / 10)
1320
1321 def perform_test_omci(self):
1322 """
1323 Perform the initial test request
1324 """
1325 ani_g_entities = self._device.configuration.ani_g_entities
1326 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1327 is not None else None
1328 self._entity_id = ani_g_entities_ids[0]
1329 self.logger.info('perform-test', entity_class=self._entity_class,
1330 entity_id=self._entity_id)
1331 try:
1332 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1333 result = yield self._device.omci_cc.send(frame)
1334 if not result.fields['omci_message'].fields['success_code']:
1335 self.logger.info('Self-Test Submitted Successfully',
1336 code=result.fields[
1337 'omci_message'].fields['success_code'])
1338 else:
1339 raise TestFailure('Test Failure: {}'.format(
1340 result.fields['omci_message'].fields['success_code']))
1341 except TimeoutError as e:
1342 self.deferred.errback(failure.Failure(e))
1343
1344 except Exception as e:
1345 self.logger.exception('perform-test-Error', e=e,
1346 class_id=self._entity_class,
1347 entity_id=self._entity_id)
1348 self.deferred.errback(failure.Failure(e))
1349
1350 */
1351
1352 // PM related heartbeat??? !!!TODO....
1353 //self._heartbeat.enabled = True
1354
mpagenko1cc3cb42020-07-27 15:24:38 +00001355 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1356 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1357 * 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 +05301358 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001359 */
1360 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001361 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001362 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001363 if pMibUlFsm.Is(ulStDisabled) {
1364 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001365 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001366 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301367 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301369 //Determine ONU status and start/re-start MIB Synchronization tasks
1370 //Determine if this ONU has ever synchronized
1371 if true { //TODO: insert valid check
1372 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001373 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001374 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001375 }
Himani Chawla4d908332020-08-31 12:30:20 +05301376 } else {
1377 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001378 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001379 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301380 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301382 //Examine the MIB Data Sync
1383 // callbacks to be handled:
1384 // Event(ulEvSuccess)
1385 // Event(ulEvTimeout)
1386 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001387 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001388 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001389 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001390 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001391 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001392 }
1393 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001394 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001395 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001396 }
1397 return nil
1398}
1399
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001401 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001402 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001403 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001405
mpagenko900ee4b2020-10-12 11:56:34 +00001406 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1407 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1408 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001409 if err := dh.resetFsms(ctx); err != nil {
1410 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001411 log.Fields{"device-id": dh.deviceID, "error": err})
1412 // abort: system behavior is just unstable ...
1413 return err
1414 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001415 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001416 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00001417
1418 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1419 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1420 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001422 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001424 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001425 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001427
1428 //TODO!!! remove existing traffic profiles
1429 /* from py code, if TP's exist, remove them - not yet implemented
1430 self._tp = dict()
1431 # Let TP download happen again
1432 for uni_id in self._tp_service_specific_task:
1433 self._tp_service_specific_task[uni_id].clear()
1434 for uni_id in self._tech_profile_download_done:
1435 self._tech_profile_download_done[uni_id].clear()
1436 */
1437
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001439
mpagenkofc4f56e2020-11-04 17:17:49 +00001440 dh.ReadyForSpecificOmciConfig = false
1441
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001443 // abort: system behavior is just unstable ...
1444 return err
1445 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001447 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001449 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001450 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001452 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001453 // abort: system behavior is just unstable ...
1454 return err
1455 }
1456 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001458 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459 return nil
1460}
1461
dbainbri4d3a0dc2020-12-02 00:33:42 +00001462func (dh *deviceHandler) resetFsms(ctx context.Context) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001463 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1464 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1465 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1466 // and using the stop/reset event should never harm
1467
dbainbri4d3a0dc2020-12-02 00:33:42 +00001468 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001469 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001470 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001471 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1472 }
mpagenko900ee4b2020-10-12 11:56:34 +00001473 //the MibSync FSM might be active all the ONU-active time,
1474 // hence it must be stopped unconditionally
1475 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1476 if pMibUlFsm != nil {
1477 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1478 }
1479 //MibDownload may run
1480 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1481 if pMibDlFsm != nil {
1482 _ = pMibDlFsm.Event(dlEvReset)
1483 }
1484 //port lock/unlock FSM's may be active
1485 if dh.pUnlockStateFsm != nil {
1486 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1487 }
1488 if dh.pLockStateFsm != nil {
1489 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1490 }
1491 //techProfile related PonAniConfigFsm FSM may be active
1492 if dh.pOnuTP != nil {
1493 // should always be the case here
1494 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1495 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001496 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1497 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1498 }
mpagenko900ee4b2020-10-12 11:56:34 +00001499 }
1500 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001501 // reset the possibly existing VlanConfigFsm
1502 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1503 //VlanFilterFsm exists and was already started
1504 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1505 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001506 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001507 // no need to remove specific data
1508 pVlanFilterFsm.RequestClearPersistency(false)
1509 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001510 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1511 }
1512 }
1513 }
1514 }
1515 //TODO!!! care about PM/Alarm processing once started
1516 return nil
1517}
1518
dbainbri4d3a0dc2020-12-02 00:33:42 +00001519func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1520 logger.Debugw(ctx, "MibInSync event received, adding uni ports and locking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301521
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1523 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001524 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001525 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001526 return
1527 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001528 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001529 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1530 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1531 for _, mgmtEntityID := range pptpInstKeys {
1532 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1533 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301535 i++
1536 }
1537 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001538 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301539 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001540 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1541 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301542 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001543 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301544 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301546 i++
1547 }
1548 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301550 }
1551 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001552 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301553 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001554 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1555 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1556 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1557 * disable/enable toggling here to allow traffic
1558 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1559 * like the py comment says:
1560 * # start by locking all the unis till mib sync and initial mib is downloaded
1561 * # this way we can capture the port down/up events when we are ready
1562 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301563
mpagenkoa40e99a2020-11-17 13:50:39 +00001564 // Init Uni Ports to Admin locked state
1565 // *** should generate UniLockStateDone event *****
1566 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001568 } else { //LockStateFSM already init
1569 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001571 }
1572}
1573
dbainbri4d3a0dc2020-12-02 00:33:42 +00001574func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1575 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301576 /* Mib download procedure -
1577 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1578 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001580 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001582 return
1583 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301584 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1585 if pMibDlFsm != nil {
1586 if pMibDlFsm.Is(dlStDisabled) {
1587 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Errorw(ctx, "MibDownloadFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301589 // maybe try a FSM reset and then again ... - TODO!!!
1590 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001591 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301592 // maybe use more specific states here for the specific download steps ...
1593 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301595 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301597 //Begin MIB data download (running autonomously)
1598 }
1599 }
1600 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001602 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301603 // maybe try a FSM reset and then again ... - TODO!!!
1604 }
1605 /***** Mib download started */
1606 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301608 }
1609}
1610
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1612 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301613 //initiate DevStateUpdate
1614 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001616 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301618 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1619 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301621 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301623 }
1624 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001626 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001627 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001628 return
1629 }
1630 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked and wait for re-enabling",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001632 log.Fields{"device-id": dh.deviceID})
1633 dh.reconciling = false
1634 return
1635 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301637 log.Fields{"device-id": dh.deviceID})
1638 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001640 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301641 // *** should generate UniUnlockStateDone event *****
1642 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301644 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301645 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301647 }
1648}
1649
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1651 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301652
1653 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301655 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1657 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001658 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001660 return
1661 }
1662 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 if err := dh.storePersistentData(ctx); err != nil {
1664 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001665 log.Fields{"device-id": dh.deviceID, "err": err})
1666 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 logger.Debugw(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Himani Chawla26e555c2020-08-31 12:30:20 +05301669 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001671 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301672 }
1673}
1674
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1676 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001677 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001679 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1680 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001682 }
1683
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001685 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001687
1688 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001690
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001692 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 return
1695 }
1696 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 if err := dh.storePersistentData(ctx); err != nil {
1698 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001699 log.Fields{"device-id": dh.deviceID, "err": err})
1700 }
mpagenko900ee4b2020-10-12 11:56:34 +00001701}
1702
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1704 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001705 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001707 voltha.OperStatus_ACTIVE); err != nil {
1708 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001710 }
1711
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001713 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001714 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001716
1717 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001719
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001721 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001723 return
1724 }
1725 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 if err := dh.storePersistentData(ctx); err != nil {
1727 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001728 log.Fields{"device-id": dh.deviceID, "err": err})
1729 }
mpagenko900ee4b2020-10-12 11:56:34 +00001730}
1731
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001733 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001735 // attention: the device reason update is done based on ONU-UNI-Port related activity
1736 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001737 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001738 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301740 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001741 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001743 }
1744 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001746 // attention: the device reason update is done based on ONU-UNI-Port related activity
1747 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001748 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001749 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001751 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001752 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301753}
1754
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1756 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001757 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301758 // attention: the device reason update is done based on ONU-UNI-Port related activity
1759 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301760
mpagenkofc4f56e2020-11-04 17:17:49 +00001761 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001762 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001763 // which may be the case from some previous actvity on another UNI Port of the ONU
1764 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001766 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001768 }
1769 }
1770 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001771 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001772 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001774 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301775 }
1776}
1777
Himani Chawla6d2ae152020-09-02 13:11:20 +05301778//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301780 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001781 case MibDatabaseSync:
1782 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001783 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001784 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001785 case UniLockStateDone:
1786 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001788 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001789 case MibDownloadDone:
1790 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001792 }
1793 case UniUnlockStateDone:
1794 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001796 }
mpagenko900ee4b2020-10-12 11:56:34 +00001797 case UniEnableStateDone:
1798 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001800 }
1801 case UniDisableStateDone:
1802 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001804 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001805 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001806 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001808 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001809 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001810 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001812 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001813 default:
1814 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001816 }
1817 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818}
1819
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001821 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301823 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001824 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001826 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301827 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001832 //store UniPort with the System-PortNumber key
1833 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001834 if !dh.reconciling {
1835 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1837 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001838 } //error logging already within UniPort method
1839 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001841 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842 }
1843 }
1844}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001845
mpagenko3af1f032020-06-10 08:53:41 +00001846// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001848 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301849 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001850 // with following remark:
1851 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1852 // # load on the core
1853
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001854 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001855
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001856 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001857 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301858 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301860 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001861 if !dh.reconciling {
1862 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001864 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001865 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001867 }
mpagenko3af1f032020-06-10 08:53:41 +00001868 }
1869 }
1870}
1871
1872// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001874 // compare enableUniPortStateUpdate() above
1875 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1876 for uniNo, uniPort := range dh.uniEntityMap {
1877 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301878 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301880 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001881 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001883 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001884 }
1885}
1886
1887// ONU_Active/Inactive announcement on system KAFKA bus
1888// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001890 var de voltha.DeviceEvent
1891 eventContext := make(map[string]string)
1892 //Populating event context
1893 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001895 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301897 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001898 }
1899 oltSerialNumber := parentDevice.SerialNumber
1900
1901 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1902 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1903 eventContext["serial-number"] = dh.device.SerialNumber
1904 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301905 eventContext["device_id"] = aDeviceID
1906 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001908 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001909
1910 /* Populating device event body */
1911 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301912 de.ResourceId = aDeviceID
1913 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001914 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1915 de.Description = fmt.Sprintf("%s Event - %s - %s",
1916 cEventObjectType, cOnuActivatedEvent, "Raised")
1917 } else {
1918 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1919 de.Description = fmt.Sprintf("%s Event - %s - %s",
1920 cEventObjectType, cOnuActivatedEvent, "Cleared")
1921 }
1922 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1924 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301925 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001926 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301928 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001929}
1930
Himani Chawla4d908332020-08-31 12:30:20 +05301931// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001933 chLSFsm := make(chan Message, 2048)
1934 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301935 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001937 sFsmName = "LockStateFSM"
1938 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001940 sFsmName = "UnLockStateFSM"
1941 }
mpagenko3af1f032020-06-10 08:53:41 +00001942
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001944 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001946 return
1947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001949 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001950 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301951 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001952 dh.pLockStateFsm = pLSFsm
1953 } else {
1954 dh.pUnlockStateFsm = pLSFsm
1955 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001957 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001959 }
1960}
1961
1962// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001964 /* Uni Port lock/unlock procedure -
1965 ***** should run via 'adminDone' state and generate the argument requested event *****
1966 */
1967 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301968 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001969 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1970 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1971 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001972 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301973 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001974 }
1975 } else {
1976 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1977 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1978 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001979 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301980 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001981 }
1982 }
1983 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001984 if pLSStatemachine.Is(uniStDisabled) {
1985 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001987 // maybe try a FSM reset and then again ... - TODO!!!
1988 } else {
1989 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001991 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001992 }
1993 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001995 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001996 // maybe try a FSM reset and then again ... - TODO!!!
1997 }
1998 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002000 // maybe try a FSM reset and then again ... - TODO!!!
2001 }
2002}
2003
Himani Chawla6d2ae152020-09-02 13:11:20 +05302004//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002006 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002008 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002009 kvbackend := &db.Backend{
2010 Client: dh.pOpenOnuAc.kvClient,
2011 StoreType: dh.pOpenOnuAc.KVStoreType,
2012 /* address config update acc. to [VOL-2736] */
2013 Address: addr,
2014 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2015 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002016
mpagenkoaf801632020-07-03 10:00:42 +00002017 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002018}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302020 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002021
mpagenkodff5dda2020-08-28 11:52:01 +00002022 for _, field := range flow.GetOfbFields(apFlowItem) {
2023 switch field.Type {
2024 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2025 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002027 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2028 }
mpagenko01e726e2020-10-23 09:45:29 +00002029 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002030 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2031 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302032 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002033 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302034 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2035 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002036 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2037 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002038 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2039 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302040 return
mpagenkodff5dda2020-08-28 11:52:01 +00002041 }
2042 }
mpagenko01e726e2020-10-23 09:45:29 +00002043 */
mpagenkodff5dda2020-08-28 11:52:01 +00002044 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2045 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302046 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002047 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302048 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002049 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302050 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002051 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002052 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302053 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002054 }
2055 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2056 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302057 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002059 "PCP": loAddPcp})
2060 }
2061 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2062 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002064 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2065 }
2066 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2067 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002069 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2070 }
2071 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2072 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002074 "IPv4-DST": field.GetIpv4Dst()})
2075 }
2076 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2077 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002078 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002079 "IPv4-SRC": field.GetIpv4Src()})
2080 }
2081 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2082 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002083 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002084 "Metadata": field.GetTableMetadata()})
2085 }
2086 /*
2087 default:
2088 {
2089 //all other entires ignored
2090 }
2091 */
2092 }
2093 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302094}
mpagenkodff5dda2020-08-28 11:52:01 +00002095
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002097 for _, action := range flow.GetActions(apFlowItem) {
2098 switch action.Type {
2099 /* not used:
2100 case of.OfpActionType_OFPAT_OUTPUT:
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 "Output": action.GetOutput()})
2104 }
2105 */
2106 case of.OfpActionType_OFPAT_PUSH_VLAN:
2107 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002108 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002109 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2110 }
2111 case of.OfpActionType_OFPAT_SET_FIELD:
2112 {
2113 pActionSetField := action.GetSetField()
2114 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002115 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002116 "OxcmClass": pActionSetField.Field.OxmClass})
2117 }
2118 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302119 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302121 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002122 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302123 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002126 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002128 "Type": pActionSetField.Field.GetOfbField().Type})
2129 }
2130 }
2131 /*
2132 default:
2133 {
2134 //all other entires ignored
2135 }
2136 */
2137 }
2138 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302139}
2140
2141//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302143 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2144 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2145 var loAddPcp, loSetPcp uint8
2146 var loIPProto uint32
2147 /* the TechProfileId is part of the flow Metadata - compare also comment within
2148 * OLT-Adapter:openolt_flowmgr.go
2149 * Metadata 8 bytes:
2150 * Most Significant 2 Bytes = Inner VLAN
2151 * Next 2 Bytes = Tech Profile ID(TPID)
2152 * Least Significant 4 Bytes = Port ID
2153 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2154 * subscriber related flows.
2155 */
2156
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302158 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302160 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002161 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302162 }
mpagenko551a4d42020-12-08 18:09:20 +00002163 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002164 loCookie := apFlowItem.GetCookie()
2165 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002166 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002167 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302168
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002170 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302171 if loIPProto == 2 {
2172 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2173 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002174 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2175 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302176 return nil
2177 }
mpagenko01e726e2020-10-23 09:45:29 +00002178 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002180
2181 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002183 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2184 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2185 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2186 //TODO!!: Use DeviceId within the error response to rwCore
2187 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002188 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002189 }
2190 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002192 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2193 } else {
2194 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2195 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2196 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302197 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002198 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002199 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002200 }
mpagenko9a304ea2020-12-16 15:54:01 +00002201
2202 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2203 dh.lockVlanConfig.Lock()
2204 defer dh.lockVlanConfig.Unlock()
2205 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302206 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002208 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002209 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002210 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002211 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002212}
2213
2214//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002216 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2217 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2218 //no extra check is done on the rule parameters
2219 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2220 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2221 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2222 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002223 // - 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 +00002224 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002226
2227 /* TT related temporary workaround - should not be needed anymore
2228 for _, field := range flow.GetOfbFields(apFlowItem) {
2229 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2230 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002231 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002232 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2233 if loIPProto == 2 {
2234 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
mpagenko551a4d42020-12-08 18:09:20 +00002235 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002236 log.Fields{"device-id": dh.deviceID})
2237 return nil
2238 }
2239 }
2240 } //for all OfbFields
2241 */
2242
mpagenko9a304ea2020-12-16 15:54:01 +00002243 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2244 dh.lockVlanConfig.Lock()
2245 defer dh.lockVlanConfig.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002246 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002248 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002250 log.Fields{"device-id": dh.deviceID})
2251 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002252 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002254
mpagenko01e726e2020-10-23 09:45:29 +00002255 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002256}
2257
Himani Chawla26e555c2020-08-31 12:30:20 +05302258// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002259// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002260func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002261 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002262 chVlanFilterFsm := make(chan Message, 2048)
2263
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002265 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302267 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002268 }
2269
dbainbri4d3a0dc2020-12-02 00:33:42 +00002270 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002271 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2272 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002273 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302274 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002275 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2276 if pVlanFilterStatemachine != nil {
2277 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2278 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002279 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302280 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002281 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302282 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002283 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302284 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2285 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002286 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002287 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002288 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302289 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002290 }
2291 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002293 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302294 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002295 }
2296 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002297 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002298 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302299 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002300 }
2301 return nil
2302}
2303
mpagenkofc4f56e2020-11-04 17:17:49 +00002304//VerifyVlanConfigRequest checks on existence of a given uniPort
2305// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002306func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002307 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2308 var pCurrentUniPort *onuUniPort
2309 for _, uniPort := range dh.uniEntityMap {
2310 // only if this port is validated for operState transfer
2311 if uniPort.uniID == uint8(aUniID) {
2312 pCurrentUniPort = uniPort
2313 break //found - end search loop
2314 }
2315 }
2316 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002318 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2319 return
2320 }
mpagenko551a4d42020-12-08 18:09:20 +00002321 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002322}
2323
mpagenkodff5dda2020-08-28 11:52:01 +00002324//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002325func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002326 //TODO!! verify and start pending flow configuration
2327 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2328 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302329 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002330 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2331 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2332 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002333 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2334 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2335 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2336 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2337 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2338 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2339 } else {
2340 /***** UniVlanConfigFsm continued */
2341 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2342 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2343 "UniPort": apUniPort.portNo})
2344 }
2345 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2346 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2347 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2348 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2349 } else {
2350 /***** UniVlanConfigFsm continued */
2351 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2352 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2353 "UniPort": apUniPort.portNo})
2354 }
mpagenkodff5dda2020-08-28 11:52:01 +00002355 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002356 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2357 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002358 "UniPort": apUniPort.portNo})
2359 }
2360 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002361 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2362 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2363 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002364 }
2365 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002366 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002367 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002368 }
mpagenkodff5dda2020-08-28 11:52:01 +00002369 } // else: nothing to do
2370}
2371
2372//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2373// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2375 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002376 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2377 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302378 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002379}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002380
2381//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2382//available for potential reconcilement
2383
dbainbri4d3a0dc2020-12-02 00:33:42 +00002384func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002385
2386 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002388 return nil
2389 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002391
dbainbri4d3a0dc2020-12-02 00:33:42 +00002392 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002393 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002395 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2396 }
2397 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2398
2399 pDevEntry.lockOnuKVStoreMutex()
2400 defer pDevEntry.unlockOnuKVStoreMutex()
2401
2402 // deadline context to ensure completion of background routines waited for
2403 //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 +05302404 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002405 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2406
2407 pDevEntry.resetKvProcessingErrorIndication()
2408 var wg sync.WaitGroup
2409 wg.Add(1) // for the 1 go routine to finish
2410
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2412 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002413
2414 return pDevEntry.getKvProcessingErrorIndication()
2415}
2416
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002418 defer cancel() //ensure termination of context (may be pro forma)
2419 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002420 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002421 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002422}
2423
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002425
2426 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002427 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002428 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002429 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2430 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002431 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002432 return err
2433 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002434 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002435 return nil
2436 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002437 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002438 return nil
2439}
2440
dbainbri4d3a0dc2020-12-02 00:33:42 +00002441func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2442 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002443 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002445 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2446 }
2447 pDevEntry.lockOnuKVStoreMutex()
2448 defer pDevEntry.unlockOnuKVStoreMutex()
2449
2450 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2451 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2452
2453 pDevEntry.resetKvProcessingErrorIndication()
2454 var wg sync.WaitGroup
2455 wg.Add(1) // for the 1 go routine to finish
2456
2457 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002459
2460 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002462 return err
2463 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002464 return nil
2465}
2466
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002467func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2468 var errStr string = ""
2469 for _, err := range errS {
2470 if err != nil {
2471 errStr = errStr + err.Error() + " "
2472 }
2473 }
2474 if errStr != "" {
2475 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2476 }
2477 return nil
2478}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002479
2480// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2481func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2482 dh.lockDevice.RLock()
2483 defer dh.lockDevice.RUnlock()
2484 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2485 return uniPort.entityID, nil
2486 }
2487 return 0, errors.New("error-fetching-uni-port")
2488}