blob: 9e02ed048b7994d155bb77136c6019010284a7df [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
165 activePorts sync.Map
166 uniEntityMap map[uint32]*onuUniPort
167 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
168 reconciling bool
169 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170}
171
Himani Chawla6d2ae152020-09-02 13:11:20 +0530172//newDeviceHandler creates a new device handler
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))
190 dh.activePorts = sync.Map{}
191 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530192 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +0000193 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000194 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000195 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196
197 // Device related state machine
198 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000199 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000200 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000201 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
202 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
203 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
204 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
205 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 },
207 fsm.Callbacks{
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.)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(ctx, me.UniGClassID); len(unigInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301530 for _, mgmtEntityID := range unigInstKeys {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 logger.Debugw(ctx, "Add UNI port for stored UniG instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301532 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301534 i++
1535 }
1536 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301538 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301540 for _, mgmtEntityID := range veipInstKeys {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Debugw(ctx, "Add VEIP acc. to stored VEIP instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301542 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301544 i++
1545 }
1546 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301548 }
1549 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301551 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001552 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1553 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1554 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1555 * disable/enable toggling here to allow traffic
1556 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1557 * like the py comment says:
1558 * # start by locking all the unis till mib sync and initial mib is downloaded
1559 * # this way we can capture the port down/up events when we are ready
1560 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301561
mpagenkoa40e99a2020-11-17 13:50:39 +00001562 // Init Uni Ports to Admin locked state
1563 // *** should generate UniLockStateDone event *****
1564 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001566 } else { //LockStateFSM already init
1567 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001569 }
1570}
1571
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1573 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301574 /* Mib download procedure -
1575 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1576 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001578 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001580 return
1581 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301582 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1583 if pMibDlFsm != nil {
1584 if pMibDlFsm.Is(dlStDisabled) {
1585 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 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 +05301587 // maybe try a FSM reset and then again ... - TODO!!!
1588 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001589 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301590 // maybe use more specific states here for the specific download steps ...
1591 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301593 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301595 //Begin MIB data download (running autonomously)
1596 }
1597 }
1598 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001600 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301601 // maybe try a FSM reset and then again ... - TODO!!!
1602 }
1603 /***** Mib download started */
1604 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301606 }
1607}
1608
dbainbri4d3a0dc2020-12-02 00:33:42 +00001609func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1610 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301611 //initiate DevStateUpdate
1612 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001614 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301616 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1617 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301619 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301621 }
1622 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001624 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001626 return
1627 }
1628 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629 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 +00001630 log.Fields{"device-id": dh.deviceID})
1631 dh.reconciling = false
1632 return
1633 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301635 log.Fields{"device-id": dh.deviceID})
1636 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001638 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301639 // *** should generate UniUnlockStateDone event *****
1640 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301642 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301643 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301645 }
1646}
1647
dbainbri4d3a0dc2020-12-02 00:33:42 +00001648func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1649 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301650
1651 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301653 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1655 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001656 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001658 return
1659 }
1660 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 if err := dh.storePersistentData(ctx); err != nil {
1662 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001663 log.Fields{"device-id": dh.deviceID, "err": err})
1664 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 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 +05301667 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001669 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301670 }
1671}
1672
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1674 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001675 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001677 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1678 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001680 }
1681
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001683 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001685
1686 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001688
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001690 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001692 return
1693 }
1694 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 if err := dh.storePersistentData(ctx); err != nil {
1696 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001697 log.Fields{"device-id": dh.deviceID, "err": err})
1698 }
mpagenko900ee4b2020-10-12 11:56:34 +00001699}
1700
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1702 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001703 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001705 voltha.OperStatus_ACTIVE); err != nil {
1706 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001708 }
1709
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001711 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001712 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001714
1715 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001717
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001719 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001721 return
1722 }
1723 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 if err := dh.storePersistentData(ctx); err != nil {
1725 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 log.Fields{"device-id": dh.deviceID, "err": err})
1727 }
mpagenko900ee4b2020-10-12 11:56:34 +00001728}
1729
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001731 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001733 // attention: the device reason update is done based on ONU-UNI-Port related activity
1734 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001735 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001736 // 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 +00001737 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.reconciling)
Himani Chawla26e555c2020-08-31 12:30:20 +05301738 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001739 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001740 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001741 }
1742 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001744 // attention: the device reason update is done based on ONU-UNI-Port related activity
1745 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001746 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001747 // 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 +00001748 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001749 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001750 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301751}
1752
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1754 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001755 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301756 // attention: the device reason update is done based on ONU-UNI-Port related activity
1757 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301758
mpagenkofc4f56e2020-11-04 17:17:49 +00001759 if aDevEvent == OmciVlanFilterAddDone {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001760 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001761 // which may be the case from some previous actvity on another UNI Port of the ONU
1762 // or even some previous flow add activity on the same port
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001764 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001766 }
1767 }
1768 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001769 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001770 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001772 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301773 }
1774}
1775
Himani Chawla6d2ae152020-09-02 13:11:20 +05301776//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301778 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001779 case MibDatabaseSync:
1780 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001782 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001783 case UniLockStateDone:
1784 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001786 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001787 case MibDownloadDone:
1788 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001790 }
1791 case UniUnlockStateDone:
1792 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001794 }
mpagenko900ee4b2020-10-12 11:56:34 +00001795 case UniEnableStateDone:
1796 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001798 }
1799 case UniDisableStateDone:
1800 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001802 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001803 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001804 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001806 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001807 case OmciVlanFilterAddDone, OmciVlanFilterRemDone:
mpagenkodff5dda2020-08-28 11:52:01 +00001808 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001809 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001810 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001811 default:
1812 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001814 }
1815 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001816}
1817
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001819 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05301821 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001822 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001824 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05301825 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001827 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001830 //store UniPort with the System-PortNumber key
1831 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001832 if !dh.reconciling {
1833 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
1835 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001836 } //error logging already within UniPort method
1837 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001838 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001839 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001840 }
1841 }
1842}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001843
mpagenko3af1f032020-06-10 08:53:41 +00001844// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001846 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05301847 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001848 // with following remark:
1849 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1850 // # load on the core
1851
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001852 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001853
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001854 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001855 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301856 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301858 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001859 if !dh.reconciling {
1860 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 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 +00001862 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02001863 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001865 }
mpagenko3af1f032020-06-10 08:53:41 +00001866 }
1867 }
1868}
1869
1870// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00001872 // compare enableUniPortStateUpdate() above
1873 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1874 for uniNo, uniPort := range dh.uniEntityMap {
1875 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05301876 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05301878 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00001879 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 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 +00001881 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001882 }
1883}
1884
1885// ONU_Active/Inactive announcement on system KAFKA bus
1886// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001888 var de voltha.DeviceEvent
1889 eventContext := make(map[string]string)
1890 //Populating event context
1891 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001893 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05301895 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001896 }
1897 oltSerialNumber := parentDevice.SerialNumber
1898
1899 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1900 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1901 eventContext["serial-number"] = dh.device.SerialNumber
1902 eventContext["olt_serial_number"] = oltSerialNumber
Himani Chawla4d908332020-08-31 12:30:20 +05301903 eventContext["device_id"] = aDeviceID
1904 eventContext["registration_id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00001906 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001907
1908 /* Populating device event body */
1909 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05301910 de.ResourceId = aDeviceID
1911 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001912 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1913 de.Description = fmt.Sprintf("%s Event - %s - %s",
1914 cEventObjectType, cOnuActivatedEvent, "Raised")
1915 } else {
1916 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1917 de.Description = fmt.Sprintf("%s Event - %s - %s",
1918 cEventObjectType, cOnuActivatedEvent, "Cleared")
1919 }
1920 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
1922 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05301923 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001924 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05301926 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001927}
1928
Himani Chawla4d908332020-08-31 12:30:20 +05301929// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001931 chLSFsm := make(chan Message, 2048)
1932 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05301933 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001935 sFsmName = "LockStateFSM"
1936 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001938 sFsmName = "UnLockStateFSM"
1939 }
mpagenko3af1f032020-06-10 08:53:41 +00001940
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00001942 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001944 return
1945 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001947 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001948 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301949 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001950 dh.pLockStateFsm = pLSFsm
1951 } else {
1952 dh.pUnlockStateFsm = pLSFsm
1953 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001955 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001957 }
1958}
1959
1960// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001962 /* Uni Port lock/unlock procedure -
1963 ***** should run via 'adminDone' state and generate the argument requested event *****
1964 */
1965 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05301966 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001967 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1968 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1969 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001970 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301971 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001972 }
1973 } else {
1974 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1975 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1976 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001977 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05301978 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001979 }
1980 }
1981 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001982 if pLSStatemachine.Is(uniStDisabled) {
1983 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001985 // maybe try a FSM reset and then again ... - TODO!!!
1986 } else {
1987 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001988 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001989 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001990 }
1991 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001993 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001994 // maybe try a FSM reset and then again ... - TODO!!!
1995 }
1996 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001998 // maybe try a FSM reset and then again ... - TODO!!!
1999 }
2000}
2001
Himani Chawla6d2ae152020-09-02 13:11:20 +05302002//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
mpagenkoaf801632020-07-03 10:00:42 +00002004 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00002006 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002007 kvbackend := &db.Backend{
2008 Client: dh.pOpenOnuAc.kvClient,
2009 StoreType: dh.pOpenOnuAc.KVStoreType,
2010 /* address config update acc. to [VOL-2736] */
2011 Address: addr,
2012 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2013 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002014
mpagenkoaf801632020-07-03 10:00:42 +00002015 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002016}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002017func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302018 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002019
mpagenkodff5dda2020-08-28 11:52:01 +00002020 for _, field := range flow.GetOfbFields(apFlowItem) {
2021 switch field.Type {
2022 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2023 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002025 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2026 }
mpagenko01e726e2020-10-23 09:45:29 +00002027 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002028 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2029 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302030 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002031 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302032 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2033 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002034 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2035 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002036 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2037 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302038 return
mpagenkodff5dda2020-08-28 11:52:01 +00002039 }
2040 }
mpagenko01e726e2020-10-23 09:45:29 +00002041 */
mpagenkodff5dda2020-08-28 11:52:01 +00002042 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2043 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302044 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002045 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302046 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002047 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302048 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002049 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002050 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302051 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002052 }
2053 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2054 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302055 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002057 "PCP": loAddPcp})
2058 }
2059 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2060 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002062 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2063 }
2064 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2065 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002067 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2068 }
2069 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2070 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002072 "IPv4-DST": field.GetIpv4Dst()})
2073 }
2074 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2075 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002076 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002077 "IPv4-SRC": field.GetIpv4Src()})
2078 }
2079 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2080 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002081 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002082 "Metadata": field.GetTableMetadata()})
2083 }
2084 /*
2085 default:
2086 {
2087 //all other entires ignored
2088 }
2089 */
2090 }
2091 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302092}
mpagenkodff5dda2020-08-28 11:52:01 +00002093
dbainbri4d3a0dc2020-12-02 00:33:42 +00002094func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002095 for _, action := range flow.GetActions(apFlowItem) {
2096 switch action.Type {
2097 /* not used:
2098 case of.OfpActionType_OFPAT_OUTPUT:
2099 {
mpagenko01e726e2020-10-23 09:45:29 +00002100 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002101 "Output": action.GetOutput()})
2102 }
2103 */
2104 case of.OfpActionType_OFPAT_PUSH_VLAN:
2105 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002106 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002107 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2108 }
2109 case of.OfpActionType_OFPAT_SET_FIELD:
2110 {
2111 pActionSetField := action.GetSetField()
2112 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002114 "OxcmClass": pActionSetField.Field.OxmClass})
2115 }
2116 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302117 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002118 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302119 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002120 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302121 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002122 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302123 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002124 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002126 "Type": pActionSetField.Field.GetOfbField().Type})
2127 }
2128 }
2129 /*
2130 default:
2131 {
2132 //all other entires ignored
2133 }
2134 */
2135 }
2136 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302137}
2138
2139//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302141 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2142 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2143 var loAddPcp, loSetPcp uint8
2144 var loIPProto uint32
2145 /* the TechProfileId is part of the flow Metadata - compare also comment within
2146 * OLT-Adapter:openolt_flowmgr.go
2147 * Metadata 8 bytes:
2148 * Most Significant 2 Bytes = Inner VLAN
2149 * Next 2 Bytes = Tech Profile ID(TPID)
2150 * Least Significant 4 Bytes = Port ID
2151 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2152 * subscriber related flows.
2153 */
2154
dbainbri4d3a0dc2020-12-02 00:33:42 +00002155 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302158 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002159 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302160 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 loTpID := flow.GetTechProfileIDFromWriteMetaData(ctx, metadata)
mpagenko01e726e2020-10-23 09:45:29 +00002162 loCookie := apFlowItem.GetCookie()
2163 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002165 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302166
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002168 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302169 if loIPProto == 2 {
2170 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2171 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002172 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2173 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302174 return nil
2175 }
mpagenko01e726e2020-10-23 09:45:29 +00002176 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002178
2179 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002181 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2182 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2183 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2184 //TODO!!: Use DeviceId within the error response to rwCore
2185 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002186 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002187 }
2188 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002190 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2191 } else {
2192 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2193 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2194 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302195 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002196 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002198 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302199 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 return dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002201 loMatchVlan, loSetVlan, loSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002202 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002204 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002205}
2206
2207//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002209 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2210 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2211 //no extra check is done on the rule parameters
2212 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2213 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2214 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2215 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002216 // - 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 +00002217 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002219
2220 /* TT related temporary workaround - should not be needed anymore
2221 for _, field := range flow.GetOfbFields(apFlowItem) {
2222 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2223 loIPProto := field.GetIpProto()
2224 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
2225 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2226 if loIPProto == 2 {
2227 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
2228 logger.Debugw("flow-remove type IpProto 2: TT workaround: ignore flow",
2229 log.Fields{"device-id": dh.deviceID})
2230 return nil
2231 }
2232 }
2233 } //for all OfbFields
2234 */
2235
2236 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002237 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002238 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002239 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002240 log.Fields{"device-id": dh.deviceID})
2241 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002242 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002243 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002244
mpagenko01e726e2020-10-23 09:45:29 +00002245 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002246}
2247
Himani Chawla26e555c2020-08-31 12:30:20 +05302248// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint16, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002250 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002251 chVlanFilterFsm := make(chan Message, 2048)
2252
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002254 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302256 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002257 }
2258
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002260 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2261 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002262 if pVlanFilterFsm != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302263 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002264 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2265 if pVlanFilterStatemachine != nil {
2266 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2267 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302269 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002270 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302271 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302273 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2274 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002275 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002277 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302278 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002279 }
2280 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002281 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002282 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302283 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002284 }
2285 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002287 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002289 }
2290 return nil
2291}
2292
mpagenkofc4f56e2020-11-04 17:17:49 +00002293//VerifyVlanConfigRequest checks on existence of a given uniPort
2294// and starts verification of flow config based on that
dbainbri4d3a0dc2020-12-02 00:33:42 +00002295func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002296 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2297 var pCurrentUniPort *onuUniPort
2298 for _, uniPort := range dh.uniEntityMap {
2299 // only if this port is validated for operState transfer
2300 if uniPort.uniID == uint8(aUniID) {
2301 pCurrentUniPort = uniPort
2302 break //found - end search loop
2303 }
2304 }
2305 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002307 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2308 return
2309 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002310 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort)
mpagenkofc4f56e2020-11-04 17:17:49 +00002311}
2312
mpagenkodff5dda2020-08-28 11:52:01 +00002313//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002314func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort) {
mpagenkodff5dda2020-08-28 11:52:01 +00002315 //TODO!! verify and start pending flow configuration
2316 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2317 //but execution was set to 'on hold' as first the TechProfile config had to be applied
Himani Chawla26e555c2020-08-31 12:30:20 +05302318 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkodff5dda2020-08-28 11:52:01 +00002319 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2320 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2321 if pVlanFilterStatemachine != nil {
2322 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2323 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00002325 } else {
2326 /***** UniVlanConfigFsm continued */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002328 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2329 "UniPort": apUniPort.portNo})
2330 }
2331 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002333 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
2334 }
2335 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002337 "device-id": dh.deviceID})
2338 }
2339
2340 } // else: nothing to do
2341}
2342
2343//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2344// 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 +00002345func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2346 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002347 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2348 //save to do, even if entry dows not exist
Himani Chawla26e555c2020-08-31 12:30:20 +05302349 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkodff5dda2020-08-28 11:52:01 +00002350}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002351
2352//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2353//available for potential reconcilement
2354
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8, aUniVlanFlowParams *[]uniVlanFlowParams) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002356
2357 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002359 return nil
2360 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002362
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002364 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002365 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002366 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2367 }
2368 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2369
2370 pDevEntry.lockOnuKVStoreMutex()
2371 defer pDevEntry.unlockOnuKVStoreMutex()
2372
2373 // deadline context to ensure completion of background routines waited for
2374 //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 +05302375 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002376 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2377
2378 pDevEntry.resetKvProcessingErrorIndication()
2379 var wg sync.WaitGroup
2380 wg.Add(1) // for the 1 go routine to finish
2381
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2383 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002384
2385 return pDevEntry.getKvProcessingErrorIndication()
2386}
2387
dbainbri4d3a0dc2020-12-02 00:33:42 +00002388func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002389 defer cancel() //ensure termination of context (may be pro forma)
2390 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002392 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002393}
2394
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002396
2397 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002398 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002399 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2401 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002402 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002403 return err
2404 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002406 return nil
2407 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002408 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002409 return nil
2410}
2411
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2413 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002414 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002416 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2417 }
2418 pDevEntry.lockOnuKVStoreMutex()
2419 defer pDevEntry.unlockOnuKVStoreMutex()
2420
2421 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2422 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2423
2424 pDevEntry.resetKvProcessingErrorIndication()
2425 var wg sync.WaitGroup
2426 wg.Add(1) // for the 1 go routine to finish
2427
2428 go pDevEntry.updateOnuKvStore(dctx, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002429 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002430
2431 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 logger.Warnw(ctx, "KV-processing error", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002433 return err
2434 }
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002435 return nil
2436}
2437
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002438func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2439 var errStr string = ""
2440 for _, err := range errS {
2441 if err != nil {
2442 errStr = errStr + err.Error() + " "
2443 }
2444 }
2445 if errStr != "" {
2446 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2447 }
2448 return nil
2449}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002450
2451// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2452func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2453 dh.lockDevice.RLock()
2454 defer dh.lockDevice.RUnlock()
2455 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2456 return uniPort.entityID, nil
2457 }
2458 return 0, errors.New("error-fetching-uni-port")
2459}